生活随笔
收集整理的這篇文章主要介紹了
Linux动态库应用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Linux動態庫應用 簡介: 動態庫調用方式一 庫函數介紹: 函數原型說明備注 void *dlopen(const char *filename, int flag) 該函數將打開一個新庫,并把它裝入內存 頭文件:dlfcn.h,編譯時需加上-ldl參數(gcc/g++) char *dlerror(void) 庫函數報錯函數 void *dlsym(void *handle, const char *symbol) 獲取庫符號的地址 void *dlclose(void *handle) 關閉庫與dlopen對應
設計一個動態庫libfunc.so 1 /* ***************************func.c********************************** */
2 #include <stdio.h>
3
4 void func()
5 {
6 printf(" this is call func " );
7 } ?
1 /* ***************************func.h********************************** */
2
3 #ifdef __FUNC_H__
4 #define __FUNC_H__
5
6 void func(void );
7
8 #endif 用如下命令生成一個動態鏈接庫: 1 linux@skytrails$ gcc -shared -fPIC -o libfunc.so func.c 設計調用libfunc.so的主函數: 1 /* ***************************main.c********************************** */
2 #include <dlfcn.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include " func.h "
6 int main() {
7 void * handle;
8 void (*pfunc)(void );
9 char *error;
10 handle = dlopen(" libfunc.so " , RTLD_NOW);
11 if (NULL == handle){
12 printf(" call dlopen failed! " );
13 exit(0 );
14 }
15 pfunc = (void (*)(void ))dlsym(handle, " func " );
16 if (NULL == pfunc){
17 error = dlerror();
18 printf(" call dlsym failed!%s " , error);
19 }
20 else {
21 (*pfunc)();
22 }
23 printf(" \n " );
24 pfunc = (void (*)(void ))dlsym(handle, " func1 " );
25 if (NULL == pfunc){
26 error = dlerror();
27 printf(" call dlsym failed!%s\n " , error);
28 }
29 else {
30 (*pfunc)();
31 }
32 printf(" \n " );
33 pfunc = (void (*)(void ))dlsym(handle, " func2 " );
34 if (NULL == pfunc){
35 error = dlerror();
36 printf(" call dlsym failed!%s\n " , error);
37 }
38 else {
39 (*pfunc)();
40 }
41 printf(" \n " );
42 pfunc = (void (*)(void ))dlsym(handle, " func3 " );
43 if (NULL == pfunc){
44 error = dlerror();
45 printf(" call dlsym failed!%s\n " , error);
46 }
47 else {
48 (*pfunc)();
49 }
50 printf(" \n " );
51 pfunc = (void (*)(void ))dlsym(handle, " func4 " );
52 if (NULL == pfunc){
53 error = dlerror();
54 printf(" call dlsym failed!%s\n " , error);
55 }
56 else {
57 (*pfunc)();
58 }
59 printf(" \n " );
60 exit(1 );
61 } 鏈接libfunc.so生成可執行文件: 1 linux@skytrails$ gcc -shared -fPIC main.c -o main -ldl 在命令行下運行可得到: 1 linux@skytrail$ ./main
2 call dlsym failed!./libfunc.so: undefined symbol: func
3 this is call func1
4 this is call func2
5 this is call func3
6 this is call func4 完整的編譯可以制作成簡易的makefile文件: 1 ################################ makefile文件 ################################
2 all:libfunc.so main
3 libfunc.so:func.c func.h
4 gcc $< -o libfunc.so -fPIC -shared
5 main:main.c
6 gcc $< -o main -ldl ?
注意事項: 調用庫函數dlopen,dlsym,dlclose時要加載庫libdl.so。 linux為程序動態庫提供了5種搜索的路徑,系統默認不搜索當前目錄,可以根據下文的動態庫搜索路徑自已選擇一種方式,否則找不到指定庫文件。 如果把func.c文件后綴改成.cpp,則會以c++方式編譯,這時會調用dlsym失敗,提示找不到func*符號。這里因為c/c++的差異,需要在函數名前指定為extern "c"。 動態庫搜索路徑 優先級路徑備注 1 DT_RPATH(ELF可執行文件中動態段) 編譯目標代碼時,對編譯器(gcc/g++)加入鏈接參數-Wl,-rpath指定動態庫搜索路徑。優先級最高 2 LD_LIBRARY_PATH Linux環境變量 3 /etc/ld.so.conf中指定動態庫路徑 不同Linux系統文件不一樣(debain)。這里是debain系統 4 /lib 默認動態為搜索路徑 5 /usr/lib
動態庫調用方式二 簡介: 第二種方式其實前面已經應用了。就是libdl.so的調用,在調用庫函數dlopen等時需要用到。下面用一個代碼實例來說明其應用。 代碼示例(libfunc.so庫復用上面代碼,makefile與main.c作一點小小的修改即可): 1 /* ****************************** main.c ***************************** */
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include " func.h "
5 int main() {
6 func1();
7 printf(" \n " );
8 func2();
9 printf(" \n " );
10 func3();
11 printf(" \n " );
12 func4();
13 printf(" \n " );
14 exit(1 );
15 } 1 ################################ makefile文件 ################################
2 all:libfunc.so main
3 libfunc.so:func.c func.h
4 gcc $< -o libfunc.so -fPIC -shared
5 main:main.c
6 gcc $< -o $@ -L. -lfunc 執行make 1 linux@skytrails$ make
2 gcc func.c -o libfunc.so -fPIC -shared
3 gcc main.c -o main -L. -lfunc 執行程序 1 linux@skytrails$ ./main
2 this is call func1
3 this is call func2
4 this is call func3
5 this is call func4
轉載于:https://www.cnblogs.com/skytrails/p/4865531.html
總結
以上是生活随笔 為你收集整理的Linux动态库应用 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。