본문 바로가기

Research/Windows

LPTHREAD_START_ROUTINE 은 stdcall 이어야만 하는가








beginthread 의 파라미터는 __cdecl 이어야 하고

beginthreadex 의 파라미터는 __stdcall 이어야 하고

CreateThread 의 파라미터는 __stdcall 이어야 하고.

__cdecl 로 작성된 함수를 스레드로 사용하려 하는데 파라미터정리를 어떻게 처리해주지 ?




갑자기; 함수 선언/정의 시에 기입하는 콜링 컨벤션의 값의 목적을 정확히 알고 싶었다.

생 뻘짓



int __cdecl funcB(int a, int b)

{ return a+b };

typedef int (__cdecl *pfB)(int, int);


int __stdcall funcA()

{

pfB fp_B = funcB;

fp_B();

}


funcA 에 써둔 __stdcall 이 영향을 미치는 범위가 어디까지인가 하는 착각에 빠졌다

혹시 funcA 안에서 호출한 함수들도 무조건 stdcall 이어야 하는가?

-_-


혹시나 테스트 해 봤는데 역시나 상관이 없다.

그저 stdcall cdecl 을 기입하는 것은 컴파일러에게 스택 정리하는 코드를 어디에 써야 하는지를 알려주는것 뿐;


함수 포인터 캐스팅 시에 콜링 컨벤션의 형변환이 올바르지 않으면 (당연히-_-;)에러가 나고

__cdecl 인지 __stdcall 인지에 따라 컴파일러가 알아서 스택정리 코드를 작성해준다.


거지같은 코드를 하나 짜봤는데



int __declspec(naked) __stdcall testFunction(int i, int j, int k)

{

__asm

{

push ebp

mov ebp, esp

push eax

...

pop eax

pop ebp

ret

}

}


이렇게 해놓고 호출하면 런타임 에러가 난다.

어쨌든 결론은

__stdcall __cdecl 의 기입은 그냥

컴파일러에게 스택 정리코드 작성 위치를 알려주는것 그 이상도 이하도 아니다.



아 그러고보니 스레드 생성에는 콜링컨벤션이 상관이 없지않나 ?

어차피 리턴해주는 esp 가 깨지는 것도 아니고 스레드별 스택이 따로있고

파라미터도 struct로 넘기는데.


위 에러나는 함수를 스레드로 돌려봤더니 잘 된다.


뭔 말도안되는 당연한걸 삽질하고있네

아오 병신