math.h math.c test.cpp
extern "C" {} 는 C언어로 만들어진 library가 C++ 컴파일러에서 동작되게끔 하려는 것이다.
C++ 컴파일러가 C로 만든 Library 를 컴파일 타임에 name mangling 하지 않도록 'extern "C" {}'를 선언함으로써 방지할 수 있다.
하지만 C컴파일러는 extern "C" 키워드를 인식하지 못하므로 C++에서만 동작하도록
__cplusplus 키워드를 추가하여 C++컴파일러에서만 동작하도록 해야 한다.
만약 extern "C" {} 없이는 complier 는 아래와 같이 에러를 출력한다.
> math.c
> test.cpp
>test.obj : error LNK2019: "int __cdecl square(int)" (?square@@YAHH@Z) 외부 기호(참조 위치: _main 함수)에서 확인하지 못했습니다.
>C:\Users\Administrator\Desktop\extern_test\Debug\extern_test.exe : fatal error LNK1120: 1개의 확인할 수 없는 외부 참조입니다.
math.c, test.cpp 는 각각 c, c++ 컴파일러에 의해 컴파일 된다.
하지만 test.cpp 가 컴파일 되기 전에 전처리기에 의해서 math.h는 치환될 것이고
#include "math.h" -> int square(int x)
그리고 컴파일 타임에 name magling 되어 어셈블리 코드에서 square 의 name이 변경되어 링킹 시점에 에러가 나게 된다.
그래서 math.h 에서 이것은 C 컴파일러로 컴파일되어야 하므로
extern "C" 키워드를 사용해서 c++ 컴파일러에 의해서 name mangling 이 되지 않도록 해야 한다.
하지만 extern "C" 에서 "C"는 c컴파일러가 받아들이지 못하는 문법이다.
그래서 c++ 표준에서는 __cplusplus 매크로를 정의한다.
c++ 컴파일러에서 컴파일 될경우 __cplusplus 매크로를 판단하여 빌드를 결정하면 된다.
#ifdef, #else, #endif
모든 functions 에 extern "C" 를 작성하는 불편을 줄이기 위해서
external linkquize block 을 사용하여 효율적으로 처리할 수 있다.
external linkquize block 을 사용하여 효율적으로 처리할 수 있다.
extern "C" {
...
}
댓글 없음:
댓글 쓰기