平時需要接觸c和c++,有時會遇到兩種語言互相呼叫動態庫的情況,這時就要對**進行一些處理,做個記錄。
兩種語言生成的庫是無法直接互相呼叫的,原因在於c++支援過載,因此存在改名機制(也可能是因為有改名機制所以支援過載 ==!)_,即生成的中間檔案會對函式名進行改寫,會將函式名與引數列表相結合生產新的函式名,這樣就可以通過不同的函式名來區分過載函式了。
而c語言沒有改名機制,函式名未改動,若兩種語言直接呼叫,便會報錯:函式名未定義。
eg:c++** ,cplus.cpp 和 cplus.h
#includeint saycplus()
#ifndef _cplus_h_
#define _cplus_h_
int saycplus();
#endif
c **,c.c和c.h
#includeint sayc()
#ifndef _c_h_
#define _c_h_
int sayc();
#endif
分別編譯成動態庫libcplus.so和libc.so
用nm 指令檢視,可知函式saycplus在動態庫中被改名了。
這時若用c呼叫libcplus.so,或c++呼叫libc.so,會顯示對函式***未定義的引用。
要實現c呼叫c++的動態庫,需要使用"extern c"關鍵字。該關鍵字是c++之父在設計c++時,為相容已存在的大量c**而設定的方法。用該關鍵字將c++的函式包含起來,即可將c++按c語言的方式進行編譯。
改寫如上**cplus.cpp
#includeextern "c"
}
重新編譯成動態庫libcplus.so,該函式不會被再改名,就可以呼叫了。
注意:<1>只在cpp中使用extern 「c」,若其他c++**包含了該標頭檔案並呼叫動態庫仍會報錯,因為標頭檔案中的函式是按c++方式(改名機制)尋找。
因此,若c++生成的動態庫要供c 和 c++呼叫,需要將cpp和標頭檔案中的函式都用extern "c"包含起來。
也可只在標頭檔案中用extern "c"括起來,在cpp中包含該標頭檔案,效果如上。
<2>用該方法c++就無法實現過載了。
<3>若c++函式的引數中使用了c中不存在的資料型別(如vector、string),或是包含了**中的其他結構,則用extern "c"包含並不能編譯通過。此時可以通過對該函式再封裝一層,入參、出參確保是通用型別即可。
c++動態庫也要用到extern "c"關鍵字,但是用在標頭檔案中。
先將c語言的標頭檔案用extern "c"包起來,c++中include該標頭檔案,即會以c的方式去尋找函式,即可實現c++呼叫c動態庫。
注意:用extern "c"包涵後,該標頭檔案就無法給c語言呼叫使用了,因此一般會加個巨集定義__cplusplus,
判斷是用c++的方式編譯,則extern 「c」 生效。
改後的標頭檔案如下:
#ifndef _c_h_
#define _c_h_
#ifdef __cplusplus
extern "c"
#endif
#endif
注意:該種方式,c的動態庫並不用改變。 Lua 和 C 互相呼叫
api有一系列的壓棧函式,為了將棧頂的lua值轉換成c值,我們為每種型別定義乙個對應的函式 void lua pushnil lua state l void lua pushboolean lua state l,int bool void lua pushnumber lua state l,d...
c 呼叫靜態庫和動態庫
呼叫靜態庫 第一步把動態庫放到檔案裡 第二部連線上靜態庫 pragma comment lib,靜態庫.lib 呼叫動態庫 第一步 typedef int getmaxnum int,int 定義乙個函式指標型別 第二部 載入 dll hmodule hmodule loadlibrary mydl...
c和lua的互相呼叫
lua和c的互相呼叫 適用於mac os 一 c呼叫lua test.c include include include include lua state l int getadd int x,int y int main int argc,char argv add.lua function a...