__stdcall 함수 포인터를 인자로 받는 함수의 오버로딩.
글쓴이: jaychoi / 작성시간: 토, 2006/12/09 - 12:51오전
__stdcall 함수 포인터를 입력으로 받는 함수와 __cdecl 함수 포인터를 입력으로 받는 템플릿 오버로딩 함수가 동시에 구체화 되면 symbol 이 이미 정의되어 있다는 에러 메세지가 발생합니다. 다음과 같은 예제에서 이런 문제가 발생합니다.
테스트 환경: DEVCPP 4.9.9.2 (g++ 3.4.2)
// #define __stdcall __attribute__((__stdcall__)) // #define __stdcall __attribute__((stdcall)) void foo(int) { } void __stdcall bar(int) { } template<class R, class P1> void bind(R (* fn)(P1)) { std::cout << "__cdecl" << std::endl; } template<class R, class P1> void bind(R (__stdcall * fn)(P1)) { std::cout << "__stdcall" << std::endl; } int main(int argc, char *argv[]) { void (* fn_cdecl)(int); void (__stdcall * fn_stdcall)(int); fn_cdecl = &foo; // OK fn_stdcall = &bar; // OK // bind( foo ); // (1) bind( bar ); // (2) system("PAUSE"); return EXIT_SUCCESS; }
위에서 (1), (2) bind 중 어느 한 경우만 있는 경우에는 컴파일 문제가 없는데 (1), (2) 동시에 있는 경우에는 다음과 같은 메세지가 발생합니다.
Assembler messages: symbol `__Z4bindIviEvPFT_T0_E' is already defined
함수 포인터에 호출 규약이 다른 경우에 오버로딩이 제대로 안되는 것으로 짐작됩니다. (물론 __stdcall 이 비 표준이긴 하지만...)
이 문제의 해결법이 없을까요?
-추가-
혹시나 해서 템플릿 bind 함수를 그냥 템플릿 제거하고 일반 함수로 하면 (1), (2) 관계없이 항상 같은 symbol이 이미 정의되어 있다는 에러를 발생시킵니다. (당연한 결과인가요? ^^)
Forums:
오버로딩은 함수
오버로딩은 함수 인자와 반환 값에 대한 정의이므로 호출 규약이 다른 같은 이름의 함수에는 사용할 수 없습니다. 다만 template에서는 호출 규약을 인식하는 것으로 보이므로 이 문제에 대해 간단한 꽁수를 생각해 볼 수 있습니다.
즉, template에서 다르게 인식한 두 함수의 인자를 다르게 주는 것입니다. (template에서 인식 한 함수가 실제로 오버로딩할 수 있는 함수로 보이게 하는 것이죠)
답변 감사.
꽁수가 아주 잘 동작하는군요. 정말로 감사드립니다.
댓글 달기