日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux动态库应用

發布時間:2024/9/5 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux动态库应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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"。
    • 動態庫搜索路徑 優先級路徑備注
      1DT_RPATH(ELF可執行文件中動態段)編譯目標代碼時,對編譯器(gcc/g++)加入鏈接參數-Wl,-rpath指定動態庫搜索路徑。優先級最高
      2LD_LIBRARY_PATHLinux環境變量
      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动态库应用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。