C C 4 C呼叫C 方法

2021-07-23 10:57:22 字數 2971 閱讀 4510

編寫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...