c和c 互相呼叫動態庫

2021-09-29 18:07:20 字數 1764 閱讀 5781

平時需要接觸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...