參考資料
網上有很多c語言編譯so庫的方法,用c++的偏少,遇見了一些坑,這裡記錄一下,以作參照。
先實現乙個最簡單的函式,libtest.cpp(先不考慮extern "c"這句話):
#include//extern "c"
double ddd(double a)
linux 命令(注意這裡生成動態庫檔案時要加上-fpic -shared):
[root@localhost jay]# g++ -fpic -shared libtest.cpp -o libtest.so
至此,so庫檔案完成。
main.cpp(這是最常見,最自然的寫法):
#include#include//extern "c"
int main(){
void *handle = dlopen("./libtest.so",rtld_lazy);
double (*ans) (double);
char *error;
ans = (double(*)(double))dlsym(handle,"ddd");
//ans = (double(*)(double))dlsym(handle,"_z3dddd");
std::cout<
[root@localhost jay]# g++ -o a.out main.cpp -ldl
可以成功執行,然而:
[root@localhost jay]# ./a.out
段錯誤
因為發現別人用c語言都是可以正常編譯的,找到wwxxlld大佬的這篇文章,利用ldd命令發現沒有依賴缺失情況,使用nm命令:
發現是g++編譯器會將函式名進行優化,以便實現c++的過載。所以最簡單的方法就是給外部使用的函式需要加上宣告,extern 「c」 函式名,讓編譯器編譯時以c語言的方式去編譯,不要優化該函式名,或者直接全域性宣告extern 「c」:
當然,你也可以直接呼叫最開始nm得到的g++優化後的新函式名_z3dddd……(雖然似乎有點蠢)。
不管怎樣,現在問題都能解決了:
[root@localhost jay]# g++ -o a.out main.cpp -ldl
[root@localhost jay]# ./a.out
4
[1]: linux 動態載入並呼叫動態庫(.so)方法介紹
[2]: linux中的nm命令簡介
[3]: 程式呼叫動態庫,編譯通過,呼叫動態庫函式執行出現undefined symbol錯誤
c 生成so呼叫LOGI
前一陣為android程式寫了一些c 生成的so檔案,但是單檔案沒法單步除錯,導致呼叫時出現問題後不好定位 於是想到在c 程式的關鍵點打logi標記,剛開始遇到些問題,後來終於解決了,現在把解決方法記錄下來,方便自己,也方便別人。首先,在c 或c的開始定義巨集,如下 定義info資訊 define ...
linux 簡單呼叫so庫
1 動態庫生成 gcc fpic shared cat.c o libcat.so o是要生成的檔案的名稱 2 編譯指令直接鏈結呼叫 gcc main.c l.lcat o test l.表示鏈結的動態庫在本地資料夾 執行可執行檔案時,需要新增本地目錄到lib目錄,否則會報 cannot open ...
so動態鏈結庫生成 呼叫
linux下檔案的型別是不依賴於其字尾名的,但一般來講 o,是目標檔案,相當於windows中的.obj檔案 so 為共享庫,是shared object,用於動態連線的,和dll差不多 a為靜態庫,是好多個.o合在一起,用於靜態連線 1 動態庫的編譯 下面通過乙個例子來介紹如何生成乙個動態庫。這裡...