Programming/C Win32 MFC2010. 9. 27. 22:00
머 언젠간 쓸일이 있겠지 -_-


GetPrivateProfileString()

[링크 : http://en.wikipedia.org/wiki/INI_file]
    [링크 : http://msdn.microsoft.com/en-us/library/ms724353%28VS.85%29.aspx]
Posted by 구차니
Programming/C Win32 MFC2010. 9. 9. 09:54
WinMain은 어플리케이션(독립 프로그램)의 ENTRY point 이고
DllMain은  Dll(라이브러리)의 ENTRY point 이다.

리눅스의 so 에서는 이런 ENTRY point가 없었는데, 먼가 생소한 느낌 -ㅁ-!

int CALLBACK WinMain(
  __in  HINSTANCE hInstance,
  __in  HINSTANCE hPrevInstance,
  __in  LPSTR lpCmdLine,
  __in  int nCmdShow
);

[링크 : http://msdn.microsoft.com/en-us/library/ms633559%28VS.85%29.aspx] WinMain

BOOL WINAPI DllMain(
  __in  HINSTANCE hinstDLL,
  __in  DWORD fdwReason,
  __in  LPVOID lpvReserved
);

[링크 : http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx] DllMain

Dll 역시 굳이 엔트리 포인트가 필요는 없으나, 단순한 함수의 모음이 아닌 특정 모듈로서의 Dll 이라
초기화가 필요하다면, 엔트리 포인트를 써야 한다고 한다.
[링크 : http://todayis.tistory.com/210]

그래도 역시 DllMain은 비어있는게 정석?!
[링크 : http://www.jiniya.net/tt/788]
Posted by 구차니
Programming/C Win32 MFC2010. 7. 19. 02:26
문득 수직탭은 들어 본적은 있는데 머하는데 쓰고,
어떻게 출력이 되는지는 모른다는 깨달음(?)을 얻었다.
검색을 해봐도 이렇다할 결과가 없긴한데...

대충 추려내자면
예전에 리본/도트 프린터 시절에 제어를 위해 존재했었는데,
프린터에서 수평탭은 8칸, 수직탭은 6줄마다 이동하도록 되어있다고 한다.
하지만, Virtual Terminal 상에서 표현은 자율에 맡기다 보니,
이상한 문자가 출력되거나, 엔터 처럼 처리되는 경우가 많은것으로 보인다.



대충 리눅스 상에서 해보니 \v (vertical tab)은 LF의 느낌이 든다.
LF(Line Feed)는 지금의 위치에서 바로 아래로 내려지게 되고, CR(Carriage Return)은 가장 앞줄로 이동하게 된다.
(타자기를 생각하면 한글자씩 쓰다가 끝까지 치게 되면 왼쪽으로 미는데 그걸 CR이라고 보면되고
종이를 밀어서 한줄 아래로 내리는걸 LF라고 보면된다.)


Posted by 구차니
Programming/C Win32 MFC2010. 7. 4. 23:50
WM_DEVICECHANGE 를 통해서 장치의 변경을 알려준다고 한다.
(머.. 내가 쓸일이 있을려나..)

[링크 : http://blog.kkomzi.net/80] << 요거 참조
[링크 : http://www.codeproject.com/kb/dotnet/devicevolumemonitor.aspx]
[링크 : http://bytes.com/topic/c-sharp/answers/264280-how-can-i-detect-cdrom-usb-device-insertions]

[링크 : http://msdn.microsoft.com/en-us/library/aa363480%28VS.85%29.aspx]
Posted by 구차니
Programming/C Win32 MFC2010. 4. 22. 14:28

#include "stdio.h"

int main(int argc, char *argv[])
{
	int x = 1;
	printf("%d %d %d\n", ++x, x, x++);
	return 0;
}

You're running into two issues:

1. Undefined behavior -- you are attempting to modify the value of an
object more than once between sequence points, and the Standard imposes
no requirement on how to handle that behavior. Basically, any
expression of the forms:

i = i++;
j = k++ * k++;
foo(i,i++,--i);

invoke undefined behavior. Read up on the semantics of the "++" and
"--" operators in an *authoritative* reference (the Standard would
obviously be one, but also K&R2 or H&S5); they don't work the way most
people think they should.

2. Order of evaluation -- AFAIK, there's no requirement that
expressions in a function parameter list be evaluated in any particular
order. At first blush, it *looks* like the arguments were evaluated
from right to left (if x = 1, then x++ evaluates to 1, with the side
effect that x == 2, and ++x evaluates to 3, with the side effect that x
== 3), but given that you've invoked undefined behavior the actual
reason may be something else entirely.

[링크 : http://bytes.com/topic/c/answers/222558-operation-x-may-undefined]

위의 소스를 gcc -Wall 옵션을 주고 컴파일 할 경우에
$ gcc -Wall cc_test.c
cc_test.c: In function ‘main’:
cc_test.c:6: warning: operation on ‘x’ may be undefined
cc_test.c:6: warning: operation on ‘x’ may be undefined
이런 경고가 발생한다.

분명 x는 변수인데, 그에 대한 operation이 정의되지 않았다는게 무슨 말인지 모르겠지만,
아무튼 실행을 하면
$ ./a.out
3 3 1
요런 희한한 결과가 나온다.

아무튼, calling convention과도 연관이 있어 보이는데,
c언어 특성상 right-left 로 push 하므로(가장 위에는 왼쪽 값이 오도록)
가장 먼저들어가는, 오른쪽 x++ 은 1이 들어가고
1을 더해준다음, 다음 명령어를 수행하면서(++x) 한번에 2가 증가하게 되고
그럼으로 인해 x, ++x 순으로 3이 들어가는게 아닐까 생각된다.

아니면 말구?

[링크 : http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html]


winXP SP3 32bit / VC++ 6 에서 해본 결과
 2 1 1


linux / gcc 결과
 3 3 1


objdump를 소스와 함께 디스어셈블 하기 위해서는
gcc -g 옵션으로 디버깅 정보를 주어야 한다.
[링크 : http://wikidocs.net/mybook/1473]


솔찍히 어셈을 몰라서 모르겠다 ㅋㅋ
결론 : 한줄에 ++나 -- 연산자를 중복으로 사용하지 말자.
Posted by 구차니
Programming/C Win32 MFC2010. 1. 6. 09:57
expat 글 보다가 무슨 말인지 몰라서 검색은 해봤는데 점점더 미궁으로 빠져드는 느낌이다 ㄱ-
일단은 call stack 관련 선언문이라는것 외에는 이해를 전혀 못하겠다 ㅠ.ㅠ

cdecl
    On the Intel 386, the cdecl attribute causes the compiler to assume that the calling function will pop off the stack space used to pass arguments. This is useful to override the effects of the -mrtd switch.
   
stdcall
    On the Intel 386, the stdcall attribute causes the compiler to assume that the called function will pop off the stack space used to pass arguments, unless it takes a variable number of arguments.
   
fastcall
    On the Intel 386, the fastcall attribute causes the compiler to pass the first two arguments in the registers ECX and EDX. Subsequent arguments are passed on the stack. The called function will pop the arguments off the stack. If the number of arguments is variable all arguments are pushed on the stack.

[링크 : http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html]

콜링 컨벤션(Calling convention)
MS방식은 5가지

__cdecl
__stdcall
__fastcall
thiscall
naked

[링크 : http://codesafe.tistory.com/94]

All arguments are widened to 32 bits when they are passed. Return values are also widened to 32 bits and returned in the EAX register, except for 8-byte structures, which are returned in the EDX:EAX register pair. Larger structures are returned in the EAX register as pointers to hidden return structures. Parameters are pushed onto the stack from right to left.

The compiler generates prolog and epilog code to save and restore the ESI, EDI, EBX, and EBP registers, if they are used in the function.

Note   When a struct, union, or class is returned from a function by value, all definitions of the type need to be the same, else the program may fail at runtime.

For information on how to define your own function prolog and epilog code, see Naked Function Calls.

The following calling conventions are supported by the Visual C/C++ compiler.

Keyword Stack cleanup Parameter passing
__cdecl Caller Pushes parameters on the stack, in reverse order (right to left)
__stdcall Callee Pushes parameters on the stack, in reverse order (right to left)
__fastcall Callee Stored in registers, then pushed on stack
thiscall
(not a keyword)
Callee Pushed on stack; this pointer stored in ECX

[링크 : http://msdn.microsoft.com/en-us/library/984x0h58%28VS.71%29.aspx]

[링크 : http://en.wikipedia.org/wiki/X86_calling_conventions]
Posted by 구차니
Programming/C Win32 MFC2009. 11. 25. 09:56
한번 시간내서 C++을 박살내고 C#을 해봐야 하는건가 ㅠ.ㅠ
아무튼,

class Class_name
{
public:
static const int i;
}

const int Class_name::i = 0;


이렇게 선언하면 클래스를 생성해도 공용으로 사용가능한 변수가 생긴다
(전역변수는 전역변수이되, 클래스 제한 전역변수일려나?)

[링크 : http://ask.nate.com/qna/view.html?n=3253901]

그냥 클래스 내부에서 public static 으로 변수 선언하면 클래스들 끼리 공유한다고 한다.




메소드는 공용으로 사용하는데, 메소드 내부 변수를 static으로 사용하면
클래스들끼리 공용하면 메소드들을 호출 할때 마다 값이 변화하므로, 의도하지 않은 값을 얻을 수 있다고 한다.

[링크 : http://ikpil.com/260]


const 의 의미
[링크 : http://www.cyworld.com/conaon/2965983]
Posted by 구차니
Programming/C Win32 MFC2009. 10. 29. 14:43
당연한 것 일수도 있지만, 조금은 황당했던 사건(!)은

static char array[]; 로 선언한 변수를
포인터로 다른 파일에 있는 함수로 넘겼을 경우, 읽지 못하고 죽어 버린다는 사실이다.

Static global variables are declared as "static" at the top level of a source file. Such variables are not visible outside the source file ("file scope"), unlike variables declared as "extern".

[링크 : http://en.wikipedia.org/wiki/Static_variable]


자세한건 나중에 다시 테스트..
Posted by 구차니
Programming/C Win32 MFC2009. 10. 27. 20:34
솔찍히 아직도 헷갈리는 녀석이 2차원 배열인데.. OTL
2차원 배열은 1차원 배열의 1차원 배열이다(응?)

array[5]는

array[0] array[1] array[2] array[3] array[4]
이고 이걸 2차원 배열로 표기하자면

array[0][0] array[0][1] array[0][2] array[0][3] array[0][4]
가 된다.(에러가 날지 안날지는 모르겠다)


아무튼
2차원 배열
array[3][2]은

array[0][0] array[0][1]
array[1][0] array[1][1]
array[2][0] array[2][1]

의 모양으로 된다.

즉,
array[행][열] 이다.


아래는 배열 주소 검증 프로그램 예제

#include "stdio.h"

int main(void)
{
        int i, j, t;
        int array[2][4], *parray;

        for( i = 0, t = 0; i < 2; i++ )
        {
                for( j = 0; j < 4; j++ )
                {
                        array[i][j] = t++;
                }
        }

        parray = &array[0][0];

        for( i = 0; i < 8; i++ )
                printf("array[%d] = %d\n", i, parray[i]);

        return 0;
}
[링크 : http://kldp.org/node/75640]


2010.09.15 추가


[링크 : http://www.cplusplus.com/doc/tutorial/arrays/]
Posted by 구차니
Programming/C Win32 MFC2009. 10. 9. 16:48
unix/linux에서는

#include <sys/stat.h>
int mkdir(const char *path, mode_t mode);

으로 디렉토리를 생성하는데

역시.. 윈도우답게, 윈도우에서는 _mkdir()을 지원한다고 한다.
문득 떠오르는 Sleep()과 sleep()의 차이점 ㄱ-

[링크 : http://msdn.microsoft.com/en-us/library/aa363855%28VS.85%29.aspx] CreateDirectory
[링크 : http://msdn.microsoft.com/en-us/library/2fkk4dzw%28VS.80%29.aspx] _mkdir
Posted by 구차니