c++通常被稱為better c,多數是因為c++程式可以很簡單的呼叫c函式,語法上基本實現相容。最常用的呼叫方式就是c++模組呼叫c實現的dll匯出函式,很簡單的用法,使用extern "c"
將c標頭檔案或者函式修飾下。
本文主要涉及到在c模組中如何呼叫c++函式,或者換個名字,extern "c"
在c語言中的功能介紹
通常,我們在需要呼叫c函式或者c實現的模組時,需要使用extern "c"
修飾下對應的部分**,告訴c++編譯器按照c的呼叫規約呼叫相關模組**。常見的形式如下:
extern "c"
近期在看jni的呼叫實現機制,不自覺的在想c能呼叫c++模組嗎?
基本的思路是來在於c++語言提供的extern "c"
機制,既然可以在c++中寫c模組,ok,那只需要乙個中間層就可以讓c呼叫c++的模組。
在c++實現如下函式:
// in header file(.h)
extern "c" int funcppdecorate(int param);
// in implenmentation file(.cpp)
int funcppdecorate(int param)
在c中按照下面方式呼叫
// declaration
int funcppdecorate(int param);
// invoke
funcppdecorate(1);
由於c不支援過載函式,如果需要c呼叫c++過載函式需要顯式的給出呼叫的方式,並在c宣告時給出對應對應機制。
在c++實現如下函式:
// in header file(.h)
void overloadfunc(int param, bool is_c=false);
void overloadfunc(double param, bool is_c=false);
extern "c"
// in implenmentation file(.cpp)
// ...
void overloaddecorate_i(int param)
void overloaddecorate_d(double param)
在c中按照下面方式呼叫
// declaration
void overloaddecorate_i(int param);
void overloaddecorate_d(double param);
// invoke
overloaddecorate_i(1);
overloaddecorate_d(2.0);
由於c++中類具有特殊的編譯器附加的構造和析構函式,為了在c中可以訪問c++的類,需要做一些c++編譯器實現的功能,比如物件的構造和析構。c不能直接使用class名稱,需要使用struct作為中轉。實現呼叫如下:
// in header file(.h)
class atype
;extern "c"
// in implenmentation file(.cpp)
// ...
extern "c" struct tagatype
;struct tagatype * createinstance()
void destoryinstance(struct tagatype ** atype)
}void classmemfunc(struct tagatype * pthis, int param)
在c中按照下面方式呼叫
// declaration
struct tagatype;
struct tagatype * createinstance();
void destoryinstance(struct tagatype ** atype);
void classmemfunc(struct tagatype * pthis, int param);
// invoke
struct tagatype * obj = createinstance();
classmemfunc(obj, 12);
destoryinstance(&obj);
g++ -c 1-c-invoke-cpp.cpp針對c++實現中的gcc -c 1-c-invoke-cpp-main.c
gcc 1-c-invoke-cpp.o 1-c-invoke-cpp-main.o -o invoke.exe
invoke
pause
extern "c"
修飾符的作用,可以使用nm命令檢視.o檔案的輸出格式,這是我使用gcc編譯後的輸出
nm 1-c-invoke-cpp.o從上面輸出可以明顯看出c++和c的函式編譯之後的修飾規則是不同的。...00000000000000ac t _z12overloadfuncdb
0000000000000041 t _z12overloadfuncib
0000000000000000 t _z6printfpkcz
0000000000000000 t _z8denyfuncv
0000000000000168 t _zn5atype7memfuncei
0000000000000150 t _zn5atypec1ev
0000000000000150 t _zn5atypec2ev
000000000000015c t _zn5atyped1ev
000000000000015c t _zn5atyped2ev
00000000000001e4 t classmemfunc
000000000000018f t createinstance
00000000000001a7 t destoryinstance
u free
000000000000001b t funcppdecorate
u malloc
000000000000012c t overloaddecorate_d
000000000000008d t overloaddecorate_i
C與C 之間相互呼叫
c與c 之間相互呼叫 1 匯出c函式以用於c或c 的專案 如果使用c語言編寫的dll,希望從中匯出函式給c或c 的模組訪問,則應使用 cplusplus 預處理器巨集確定正在編譯的語言。如果是從c 語言模組使用,則用c鏈結宣告這些函式。如果使用此技術並為dll提供標頭檔案,則這些函式可以原封不動地由...
C與C 之間相互呼叫
1 匯出c函式以用於c或c 的專案 如果使用c語言編寫的dll,希望從中匯出函式給c或c 的模組訪問,則應使用 cplusplus 預處理器巨集確定正在編譯的語言。如果是從c 語言模組使用,則用c鏈結宣告這些函式。如果使用此技術並為dll提供標頭檔案,則這些函式可以原封不動地由c和c 模組使用。以下...
C與C 之間相互呼叫
1 匯出c函式以用於c或c 的專案 如果使用c語言編寫的dll,希望從中匯出函式給c或c 的模組訪問,則應使用 cplusplus 預處理器巨集確定正在編譯的語言。如果是從c 語言模組使用,則用c鏈結宣告這些函式。如果使用此技術並為dll提供標頭檔案,則這些函式可以原封不動地由c和c 模組使用。以下...