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

歡迎訪問 生活随笔!

生活随笔

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

linux

LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror

發布時間:2023/12/13 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

dlopen

基本定義

  功能:打開一個動態鏈接庫?
  包含頭文件:?
  #include <dlfcn.h>?
  函數定義:?
  void * dlopen( const char * pathname, int mode );?
  函數描述:?
  在dlopen的()函數以指定模式打開指定的動態連接庫文件,并返回一個句柄給調用進程。使用dlclose()來卸載打開的庫。?
  mode:分為這兩種?
  RTLD_LAZY 暫緩決定,等有需要時再解出符號?
  RTLD_NOW 立即決定,返回前解除所有未決定的符號。?
  RTLD_LOCAL?
  RTLD_GLOBAL 允許導出符號?
  RTLD_GROUP?
  RTLD_WORLD?
  返回值:?
  打開錯誤返回NULL?
  成功,返回庫引用?
  編譯時候要加入 -ldl (指定dl庫)?
  例如?
  gcc test.c -o test -ldl
編輯本段
使用 dlopen
  dlopen()是一個強大的庫函數。該函數將打開一個新庫,并把它裝入內存。該函數主要用來加載庫中的符號,這些符號在編譯的時候是不知道的。比如 Apache Web 服務器利用這個函數在運行過程中加載模塊,這為它提供了額外的能力。一個配置文件控制了加載模塊的過程。這種機制使得在系統中添加或者刪除一個模塊時,都不需要重新編譯了。?
  可以在自己的程序中使用 dlopen()。dlopen() 在 dlfcn.h 中定義,并在 dl 庫中實現。它需要兩個參數:一個文件名和一個標志。文件名可以是我們學習過的庫中的 soname。標志指明是否立刻計算庫的依賴性。如果設置為 RTLD_NOW 的話,則立刻計算;如果設置的是 RTLD_LAZY,則在需要的時候才計算。另外,可以指定 RTLD_GLOBAL,它使得那些在以后才加載的庫可以獲得其中的符號。?

  當庫被裝入后,可以把 dlopen() 返回的句柄作為給 dlsym() 的第一個參數,以獲得符號在庫中的地址。使用這個地址,就可以獲得庫中特定函數的指針,并且調用裝載庫中的相應函數。

?

NOTE: 如果pathname是NULL, 則返回的是調用dlopen的模塊的庫引用(handle)。 例如: 如果我們在我們的APP里面調用dlopen去動態load一個.so, 但是pathname傳入的是NULL, 則dlopen最后返回的應該是該APP的引用(handle)

Additional link:?http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html

--------------------------------------------------------------------------------------------------------------------------

dlsym
  ?
  dlsym()的函數原型是?
  void* dlsym(void* handle,const char* symbol)?
  該函數在<dlfcn.h>文件中。?
  handle是由dlopen打開動態鏈接庫后返回的指針,symbol就是要求獲取的函數的名稱,函數返回值是void*,指向函數的地址,供調用使用

取動態對象地址:
#include <dlfcn.h>
void *dlsym(void *pHandle, char *symbol);
dlsym根據動態鏈接庫操作句柄(pHandle)與符號(symbol),返回符號對應的地址。
使用這個函數不但可以獲取函數地址,也可以獲取變量地址。比如,假設在so中
定義了一個void mytest()函數,那在使用so時先聲明一個函數指針:
void (*pMytest)(),然后使用dlsym函數將函數指針pMytest指向mytest函數,
pMytest = (void (*)())dlsym(pHandle, "mytest");

--------------------------------------------------------------------------------------------------------------------------

dlclose
  dlclose()?
  包含頭文件:?
  #include <dlfcn.h>?
  函數原型為:?
  int dlclose (void *handle);?
  函數描述:?
   dlclose用于關閉指定句柄的動態鏈接庫,只有當此動態鏈接庫的使用計數為0時,才會真正被系統卸載。

--------------------------------------------------------------------------------------------------------------------------

dlerror
  dlerror()?
  包含頭文件:?
  #include <dlfcn.h>?
  函數原型:?
  const char *dlerror(void);?
  函數描述:?
  當動態鏈接庫操作函數執行失敗時,dlerror可以返回出錯信息,返回值為NULL時表示操作函數執行成功。

LINUX創建與使用動態鏈接庫并不是一件難事。
  編譯函數源程序時選用-shared選項即可創建動態鏈接庫,注意應以.so后綴命名,最好放到公用庫目錄(如/lib,/usr/lib等)下面,并要寫好用戶接口文件,以便其它用戶共享。
  使用動態鏈接庫,源程序中要包含dlfcn.h頭文件,寫程序時注意dlopen等函數的正確調用,編譯時要采用-rdynamic選項與-ldl選項 ,以產生可調用動態鏈接庫的執行代碼

?

EXAMPLE

Load the math library, and print the cosine of 2.0:?

#include <stdio.h>

#include <dlfcn.h>

?

int main(int argc, char **argv) {

? ? void *handle;

? ? double (*cosine)(double);

? ? char *error;

?

? ? handle = dlopen ("libm.so", RTLD_LAZY);

? ? if (!handle) {

? ? ? ? fprintf (stderr, "%s\n", dlerror());

? ? ? ? exit(1);

? ? }

?

? ? cosine = dlsym(handle, "cos");

? ? if ((error = dlerror()) != NULL) ?{

? ? ? ? fprintf (stderr, "%s\n", error);

? ? ? ? exit(1);

? ? }

? ?printf ("%f\n", (*cosine)(2.0));

? ? dlclose(handle);

? ? return 0;

}

---------------------------------------------------------------------------------------------------

?If this program were in a file named "foo.c", you would build the program with the following command:?

?gcc -rdynamic -o foo foo.c -ldl

總結

以上是生活随笔為你收集整理的LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror的全部內容,希望文章能夠幫你解決所遇到的問題。

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