編寫c++原始檔:cpplib.h和cpplib.cpp。
cpplib.h:
#pragma once
#include
using
namespace
std;
class cpplib;
cpplib.cpp:
#include "cpplib.h"
cpplib::cpplib()
int cpplib::add(int x, int y)
cpplib::~cpplib()
將其封裝(extern 「c」)成c可以呼叫函式,檔案clib.h和clib.cpp如下:
clib.h:
#pragma once
#include "cpplib.h"
#ifdef __cplusplus
extern "c"
#endif // __cplusplus
clib.cpp:
#include "clib.h"
int c_add(int x, int y)
將其編譯成.so的動態庫:g++ -shared -o libclib.so cpplib.cpp clib.cpp。
測試原始檔main.c如下:
#include
#include "clib.h"
int main()
編譯:g++ -o main.out main.c ./libclib.so
(這裡一定要用g++,如果用gcc會出錯,因為gcc編譯c++檔案才會自動呼叫g++,但如果物件直接就是c檔案就不會呼叫g++了)
執行:./main.out
注:這個方法好像沒有什麼用,因為最終還是用g++編譯的,例如用下面的測試方法也是可以成功的
上面的方法最終還是g++來編譯的,不能算是是真正意義上的用c**來呼叫c++**,但是可以用linux提供的一組api(dlfcn.h)來完成,先介紹這幾個api:
dlopen
函式原型:void *dlopen(const char *libname, int flag);
功能描述:dlopen必須在dlerror,dlsym和dlclose之前呼叫,表示要將庫裝載到記憶體,準備使用。如果要裝載的庫依賴於其它庫,必須首先裝載依賴庫。如果dlopen操作失敗,返回null值;如果庫已經被裝載過,則dlopen會返回同樣的控制代碼。引數中的libname一般是庫的全路徑,這樣dlopen會直接裝載該檔案;如果只是指定了庫名稱,在dlopen會按照下面的機制去搜尋:
a.根據環境變數ld_library_path查詢
b.根據/etc/ld.so.cache查詢
c.查詢依次在/lib和/usr/lib目錄查詢。
flag引數表示處理未定義函式的方式,可以使用rtld_lazy或rtld_now。rtld_lazy表示暫時不去處理未定義函式,先把庫裝載到記憶體,等用到沒定義的函式再說;rtld_now表示馬上檢查是否存在未定義的函式,若存在,則dlopen以失敗告終。
dlerror
函式原型:char *dlerror(void);
功能描述:dlerror可以獲得最近一次dlopen,dlsym或dlclose操作的錯誤資訊,返回null表示無錯誤。dlerror在返回錯誤資訊的同時,也會清除錯誤資訊。
dlsym
函式原型:void *dlsym(void *handle,const char *symbol);
功能描述:在dlopen之後,庫被裝載到記憶體。dlsym可以獲得指定函式(symbol)在記憶體中的位置(指標)。如果找不到指定函式,則dlsym會返回null值。但判斷函式是否存在最好的方法是使用dlerror函式,
dlclose
函式原型:int dlclose(void *);
功能描述:將已經裝載的庫控制代碼減一,如果控制代碼減至零,則該庫會被解除安裝。如果存在析構函式,則在dlclose之後,析構函式會被呼叫。
下面示例仍然使用上面四個檔案生成的c++動態庫,此次測試檔案為:
main.c:
#include
#include
//#include "clib.h" //這裡好像標頭檔案都用不上了
#include //引用標頭檔案
int main()
typedef
int (*cpf)(int, int); //要用到的函式型別
dlerror();
char *error;
cpf p = (cpf)dlsym(handle, "c_add"); //要呼叫的函式
if((error = dlerror())!=null)
printf("c_add in clib.h is %d\n", p(2, 3)); //呼叫
dlclose(handle); //關閉
return
0;}
編譯:gcc -o main.out main.c ./libclib.so -ldl
執行:./main.out
C C 4 C與C 中字串的型別差異
c c 中的每乙個文字元 常量 都有一種與其相關的型別資訊。數字字元 例如10 會用int做為它的型別。即sizeof 10 與sizeof int 是相等的。但是,文字字元 例如 a 會有不同型別。在c中,文字字元被當作int型別,但是在c 中,會被當作是char型別,即c 中sizeof a 與...
C和C 混編,c呼叫C ,c 呼叫C
這兩天一直在解決這樣的乙個問題,專案之中有如下的需求 嵌入式的產品,演算法部分用c 實現,而控制程式和其它程式用c實現.這就要求可以通過c來呼叫c 的演算法程式.同時,這個專案有乙個pc的demo程式,是用vc開發的,這又要求c 能呼叫c的主控程式.一直知道應該用extern,但是具體該如何使用,一...
C 呼叫C方法
1,編譯靜態庫 libtest.a gcc c test.c o test.o ar rc libtest.a test.o 2,編譯main函式 g o main main.cpp i.test l.test static ltest test相關檔案放在了當前的test目錄下 root lear...