采用dlopen、dlsym、dlclose dlopen dlerror加载动态链接库【总结】
生活随笔
收集整理的這篇文章主要介紹了
采用dlopen、dlsym、dlclose dlopen dlerror加载动态链接库【总结】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、前言為了使程序方便擴展,具備通用性,可以采用插件形式。采用異步事件驅動模型,保證主程序邏輯不變,將各個業務已動態鏈接庫的形式加載進來,這就是所謂的插件。linux提供了加載和處理動態鏈接庫的系統調用,非常方便。本文先從使用上進行總結,涉及到基本的操作方法,關于動態鏈接庫的本質及如何加載進來,需要進一步學習,后續繼續補充。如何將程序設計為插件形式,挖掘出主題和業務之間的關系,需要進一步去學習。2、生產動態鏈接庫編譯參數 gcc -fPIC -shared 例如將如下程序編譯為動態鏈接庫libcaculate.so,程序如下: //caculate.c
int add(int a,int b)
{return (a + b);
}int sub(int a, int b)
{return (a - b);
}
編譯如下:?gcc -fPIC -shared caculate.c -o libcaculate.so?
3、dlopen、dlsym函數介紹在linux上man dlopen可以看到使用說明,函數聲明如下:#include <dlfcn.h>void *dlopen(const char *filename, int flag);char *dlerror(void);void *dlsym(void *handle, const char *symbol);int dlclose(void *handle); dlopen以指定模式打開指定的動態連接庫文件,并返回一個句柄給調用進程,dlerror返回出現的錯誤,dlsym通過句柄和連接符名稱獲取函數名或者變量名,dlclose來卸載打開的庫。 dlopen打開模式如下: RTLD_LAZY 暫緩決定,等有需要時再解出符號 RTLD_NOW 立即決定,返回前解除所有未決定的符號。采用上面生成的libcaculate.so,寫個測試程序如下: #include <stdio.h> #include <stdlib.h> #include <dlfcn.h>//動態鏈接庫路徑 #define LIB_CACULATE_PATH "./libcaculate.so"//函數指針 typedef int (*CAC_FUNC)(int, int);int main() {void *handle;char *error;CAC_FUNC cac_func = NULL;//打開動態鏈接庫handle = dlopen(LIB_CACULATE_PATH, RTLD_LAZY);if (!handle) {fprintf(stderr, "%s\n", dlerror());exit(EXIT_FAILURE);}//清除之前存在的錯誤 dlerror();//獲取一個函數//*(void **) (&cac_func) = dlsym(handle, "add");//這兩種形式是一樣的。cac_func= dlsym(handle, "add");if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error);exit(EXIT_FAILURE);}printf("add: %d\n", (*cac_func)(2,7));cac_func = (CAC_FUNC)dlsym(handle, "sub");printf("sub: %d\n", cac_func(9,2));//關閉動態鏈接庫 dlclose(handle);exit(EXIT_SUCCESS); }
編譯選項如下:gcc -rdynamic -o main main.c -ldl
測試結果如下所示:
http://www.cnblogs.com/Anker/p/3746802.html
參考資料:
http://blog.csdn.net/uusad/article/details/10208665
編譯如下:?gcc -fPIC -shared caculate.c -o libcaculate.so?
3、dlopen、dlsym函數介紹在linux上man dlopen可以看到使用說明,函數聲明如下:#include <dlfcn.h>void *dlopen(const char *filename, int flag);char *dlerror(void);void *dlsym(void *handle, const char *symbol);int dlclose(void *handle); dlopen以指定模式打開指定的動態連接庫文件,并返回一個句柄給調用進程,dlerror返回出現的錯誤,dlsym通過句柄和連接符名稱獲取函數名或者變量名,dlclose來卸載打開的庫。 dlopen打開模式如下: RTLD_LAZY 暫緩決定,等有需要時再解出符號 RTLD_NOW 立即決定,返回前解除所有未決定的符號。采用上面生成的libcaculate.so,寫個測試程序如下: #include <stdio.h> #include <stdlib.h> #include <dlfcn.h>//動態鏈接庫路徑 #define LIB_CACULATE_PATH "./libcaculate.so"//函數指針 typedef int (*CAC_FUNC)(int, int);int main() {void *handle;char *error;CAC_FUNC cac_func = NULL;//打開動態鏈接庫handle = dlopen(LIB_CACULATE_PATH, RTLD_LAZY);if (!handle) {fprintf(stderr, "%s\n", dlerror());exit(EXIT_FAILURE);}//清除之前存在的錯誤 dlerror();//獲取一個函數//*(void **) (&cac_func) = dlsym(handle, "add");//這兩種形式是一樣的。cac_func= dlsym(handle, "add");if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error);exit(EXIT_FAILURE);}printf("add: %d\n", (*cac_func)(2,7));cac_func = (CAC_FUNC)dlsym(handle, "sub");printf("sub: %d\n", cac_func(9,2));//關閉動態鏈接庫 dlclose(handle);exit(EXIT_SUCCESS); }
編譯選項如下:gcc -rdynamic -o main main.c -ldl
測試結果如下所示:
http://www.cnblogs.com/Anker/p/3746802.html
參考資料:
??http://blog.chinaunix.net/uid-26285146-id-3262288.html
??http://www.360doc.com/content/10/1213/22/4947005_77867631.shtml
??
dlopen第三方動態庫時經常會發生打開失敗的錯誤,可以適用dlerror()函數查看具體錯誤:void *dlh; dlh = dlopen("libdes3-32.so", RTLD_NOW | RTLD_GLOBAL); if (dlh == NULL) { printf("dlopen err:%s.\n",dlerror()); } 如果錯誤信息與ELF格式相關,一般是第三方庫的編譯環境與本地環境差別所致,如不同的處理器體系結構。 采用file命令可以查看動態庫的具體信息:# file libhsbcpwd.so libhsbcpwd.so: ELF 32-位 MSB 動態庫 SPARC 版本 1,動態鏈接,沒有除去,無可用的調試信息 # file libdes3-32.so libdes3-32.so: ELF 32-位 LSB 動態庫 80386 版本 1,動態鏈接,沒有除去,無可用的調試信息 MSB是Most Significant Bit的縮寫,最高有效位。在二進制數中,MSB是最高加權位。與十進制數字中最左邊的一位類似。通常,MSB位于二進制數的最左側,LSB位于二進制數的最右側。 LSB(Least Significant Bit),意為最低有效位;MSB(Most Significant Bit),意為最高有效位,若MSB=1,則表示數據為負值,若MSB=0,則表示數據為正。SPARC:SUN和TI公司合作開發的RISC微處理器。80386:INTEL處理器。x86架構是可變指令長度的CISC(復雜指令集計算機,Complex Instruction Set Computer)。http://blog.csdn.net/uusad/article/details/10208665
?
總結
以上是生活随笔為你收集整理的采用dlopen、dlsym、dlclose dlopen dlerror加载动态链接库【总结】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .net中如何生成不重复的随机数
- 下一篇: ML 徒手系列 最大似然估计