먼저 name mangling이라는것을 알아보았다.
하여튼 이넘때문에 C에서 C++에서 작성한 라이브러리를 사용하고 싶을때는 C++ 라이브러리를 작성할때 애초에 C에서 사용될수 있다는것을 염두해 두고 작성해야 한다는 말이다.
즉 C에서 호출할수 있도록 extern "C"를 선언하는 것이다.
역시 코드로 보자
C++ 라이브러리쪽
cpp.h
extern "C" void cpp_create( void ) ;
extern "C" void cpp_destroy( void ) ;
extern "C" void cpp_print( const char * ) ;
cpp.c
class dummy {
void print( const char* msg ) {
printf( msg ) ;
}
} ;
static dummy* _theDummy = NULL ;
void cpp_create( void )
{
if( _theDummy == NULL )
{
_theDummy = new dummy ;
}
}
void cpp_destroy( void )
{
if( _theDummy )
{
delete _theDummy ;
}
}
void cpp_print( const char* msg )
{
if( _theDummy )
{
_theDummy->print( msg ) ;
}
}
cpp.h파일에서 보는 봐야 같이 C에서도 사용 되는 넘들은 extern "C"를 선언했다.
반대로
CPP에서 C에서 작성한 라이브러리 사용하려면 어떻게 할까?
여기서도 마찬가지로 모든 함수에 extern "C"를 무조건 선언하는 것이다.
즉 C에서 사용되던 C++에서 사용되던 같은 이름이 사용되도록 extern "C"를 붙여 둠으로써 어디서든 같은 이름으로 링크되는것을 보장해 준다.
먼소린지 모르겠다고? 흠..
즉 C에서 작성한 라이브러리는 .h 파일과 .lib파일로 구성되어 있을것이다.
c.h
void c_func(void) ;
c.c
void c_func( void )
{
printf( "여기는 C") ;
}
이 라이브러리를 C언어를 사용하는 프로젝트에서 사용하는경우 같은 환경임으로 아무 문제 없이 링크가 수행될테지만 만약 C++소스에서 호출되는 경우 link에러가 발생하게 된다.
즉 어떤 CPP파일
call.cpp
#include "c.h"
void main( void )
{
c_func( ) ;
}
요런 경우 링크에러다. 즉 CPP에서는 C에서와는 다른 name mangling을 수행함으로 c_func라는 함수 이름을 c_func@@XXYYZ 이런식으로 찾을꺼라는 말이다. 그럼 당연이 그런 이름에 함수가 없음으로 에러가 발생한다.
즉 이렇듯 c++에서도 사용 가능하게 하려면 name mangling을 C 형태로 수행하도록 하면 되는것이다.
c.h
extern "C" void c_func( void ) ;
이것처럼 c 에서 작성하는 라이브러리에 함수는 무조건 extern "C" 를 지정하는 것이다.
이상..
방금 C에서 C++로 만든 lib에서 export한 함수를 호출해 봤더니 이런 에러가 나더군
Linking...
caller_namemangling.obj : error LNK2001: unresolved external symbol _func_a
Debug/caller_namemangling.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
즉 c쪽에서는 func_a() 라는 함수를 호출했지만 이넘이 C++쪽에서 만들어진 넘이라 이름이 좀 다르다 앞에서 설명했던것처럼 func_a@@XXYYZ 뭐 이런식에 이름이였을것이다. 따라서 링크할때 찾을수 없어서 에러가 나는것이다.
그 역도 마찬가지
EOF