使用extern "C" 主要是因爲C編譯器編譯函數時不帶參數的類型信息,只包含函數的符號名字。
如int foo( float x ),C編譯器會將此函數編譯成類似_foo的符號,C連接器只要找到了調用函數的符號,就認爲連接成功。 而C++編譯器爲了實現函數重載,會在編譯時帶上函數的參數信息。如它可以把上面的函數編譯成類似於_foo_float這樣的符號。 所以,C調用C++,使用extern "C"則是告訴編譯器依照C的方式來編譯封裝接口,當然接口函數裏面的C++語法還是按C++方式編譯。 如: // C++ Code extern "C" int foo( int x ); int foo( int x ) { //... } 這樣,編譯器會將foo函數編譯成類似_foo符號,而不會編譯成類似_foo_int符號; 則C可以這樣調用C++函數 // C Code int foo( int x ); void cc( int x ) { foo( x ); //... }
如果想調用重載的C++函數,則須封裝單獨的接口共C調用。 如 // C++ Code void foo( int x ); void foo( float x ); extern "C" void foo_i( int x ) { foo( x ); } extern "C" void foo_f( float x ) { foo( x ); } 則C中可這樣調用 // C Code void foo_i( int x ); void foo_f( float x ); void ccc( int x1, float x2 ) { foo_i( x1 ); foo_f( x2 ); // ... }
而C++調用C編譯好的模塊,如DLL或.o,這時C++會用C++的方式解釋函數名字,但C編譯後的名字是C規則的。
在C++中,在被調用的C函數的聲明前加上extern "C" 的作用是:讓C++連接器在調用函數的符號時採用C的方式 如: // C Code void foo( int x ); C++這樣調用C函數 // C++ Code extern "C" void foo( int x ); 就是讓C++連接器能過類似於_foo來查找此函數,而非類似於_foo_int這樣的符號。