간단하게 아래와 같은 프로그램이 있다고 할 때
( 파일 확장자는 .cpp로 하여 CPP style로 compile 해야 합니다. )
add_1(), fadd_2(), add_3() 가 compile되어 어떻게 이름이 바뀌는지 보면
왜 extern "C" 가 필요한지 알 수 있습니다.
#include "stdio.h"
int add_1(int a, int b);
float fadd_2(int a, int b);
extern "C" int add_3(int a, int b);
int main()
{
int a = 2, b = 3;
int c;
float fc;
c = add_1(a, b);
fc = fadd_2(a, b);
c = add_3(a, b);
return 0;
}
/********* 시험삼아 여기를 막는다
int add_1(int a, int b)
{
return a + b;
}
float fadd_2(int a, int b)
{
return (float)(a + b);
}
int add_3(int a, int b)
{
return a + b;
}
********/
################### compile/link 결과 ###############################
naver.obj : error LNK2001: unresolved external symbol _add_3
naver.obj : error LNK2001: unresolved external symbol "float __cdecl fadd_2(int,int)" (?fadd_2@@YAMHH@Z)
naver.obj : error LNK2001: unresolved external symbol "int __cdecl add_1(int,int)" (?add_1@@YAHHH@Z)
compile/link 하면 위와 같이 link error가 발생합니다.
자세히 보면
add_1 -> ?add_1@@YAHHH@Z
fadd_2 -> ?fadd_2@@YAMHH@Z
add_3 -> _add_3
와 같이 compile과정에서 이름이 바뀌어집니다.
add_1(), fadd_2()는 CPP style의 decorated name(?) 으로 바뀐 것이며
add_3()는 prototype에서 extern "C" 를 주었으므로 C style로 '_'만 앞에
붙은 것이 차이점입니다.
이상의 실험에서
CPP는 argument, return value에 따라 이름을 바꾸게 하여 반드시 protype과 일치하는 function이 link되도록 합니다. argument가
틀린 경우에는 같은 이름의 function이 여러개 존재할 수 있으며 argument에 따라 적당한 function이 link됩니다.
C는 단순히 이름앞에 '_' 만 추가되므로 argument가 틀리던 return value type이 틀리던 link는 될 수 있습니다. 심하게 잘못되면
compile/link는 되는데 오동작을 할 수도 있겠지요.
이렇게 같은 이름의 function이라도 C style, CPP style로 compile되면서
이름이 바뀌므로 C에서 CPP로 작성된 function을 참조하거나 CPP에서 C로
작성된 function을 참조할 수가 없습니다.
이럴때 extern "C" 를 사용하여 CPP에서 정의/참조 되는 function 이름을 C style로 강제로 바꾸는 것입니다.
보통 *.h file에 아래와 같이 하여 *,c, *,cpp 에서 공용할 수 있는
protype 선언을 합니다.
#if defined(__cplusplus)
extern "C" {
#endif
int func1();
int func2();
.
.
.
#if defined(__cplusplus)
};
'Work' 카테고리의 다른 글
| Visual Studio의 fflush 이야기 (1) | 2007/11/20 |
|---|---|
| TimeAttack (0) | 2007/03/29 |
| Buffering Error (0) | 2006/05/18 |
| Builder Listview Column Sorting (0) | 2006/03/31 |
| Variant Conversion (0) | 2006/03/31 |
| "extern C"에 대하여 (0) | 2006/03/30 |