Linking C & C++ Object

C++의 경우 함수의 오버로딩을 지원하기 위해 함수를 Name Mangling하여 컴파일한다.
다시 말하자면, 모든 함수들이 고유한 이름 주소를 가질 수 있도록 한다.
반면 C의 경우 모든 함수들이 그 자체로 고유한 이름을 가지고 있기 때문에 Name Mangling이 필요하지 않다.

g++로 C를 컴파일하게되면 기존의 C 함수들이 Name Mangling되게되고,
이로 인해 해당 파일 외부에서는 C 함수를 호출할 수 없다. (이름이 달라지기 때문)

이를 막기 위해서는 C 헤더에 C로 선언되었다는 것을 명시해야 한다.
이러한 역할을 하는 것이 export “C”이다.

예를들어 a.c 파일과 b.cpp 파일이 있고, b.cpp에서는 a.c에 있는 함수를 사용한다고 하자.
a.c를 gcc로, b.cpp를 g++로 컴파일하여 목적파일을 만들고, 이를 링크하려 한다.
이 경우 일반적인 빌드과정으로는 Undefined Reference 에러를 띄우게 된다. (Name Mangling)

이를 해결하기 위해서는 a.h에서 b.cpp에서 사용될 함수를 extern “C”로 지정해주면 된다.
다만 주의해야하는 것은 extern “C” 용법은 C에서 지원하지 않는 용법이라는 점인데
C++에서 헤더를 읽을 때만 extern “C”가 적용될 수 있도록 다음과 같이 처리해주면 된다.

#ifdef __cplusplus
extern "C" {
#endif

aio_controller *aio_controller_init();
void aio_controller_begin(aio_controller *controller, char *dev, int baudrate);
void aio_controller_free(aio_controller **controller);

void aio_routine(char *dev, int baudrate);
void aio_inner_routine(void);
void aio_debug_test_function(void);
void aio_cleanup(void);
int aio_get_db_insert_string(aio_data_package *data, char *query);
char *aio_get_db_print_string(void);

#ifdef __cplusplus
}
#endif

정리하면
1. C에서 C++에 사용될 함수부분을 extern “C”로 지정(혹은 헤더 전체를 extern “C”로 지정하여도 무방)
2. 일반적인 빌드과정을 그대로 따름 (gcc, g++로 각각 컴파일 후 링크)

댓글 남기기