#include #include typedef struct __test test;
void __register(test *p)
static void __printf(test *p)
//這種 ".成員"的賦值方式為c99標準
static test config = ;
//載入動態庫的自動初始化函式
void _init(void)
main函式
#include #include #include int main(void)
return 0;
}
主程式編譯: gcc test.c -o test -ldl -rdynamic
動態庫編譯: gcc -shared -fpic -nostartfiles -o mylib.so mylib.c
主程式通過dlopen()載入乙個.so的動態庫檔案, 然後動態庫會自動執行 _init() 初始化函式, 初始化函式列印乙個提示資訊, 然後呼叫主程式的註冊函式給結構體重新賦值, 然後呼叫結構體的函式指標, 列印該結構體的值. 這樣就充分的達到了主程式和動態庫的函式相互呼叫和指標的相互傳遞.
gcc引數 -rdynamic 用來通知鏈結器將所有符號新增到動態符號表中(目的是能夠通過使用 dlopen 來實現向後跟蹤).
gcc引數 -fpic 作用: 當使用.so等類的庫時,當遇到多個可執行檔案共用這乙個庫時, 在記憶體中,這個庫就不會被複製多份,讓每個可執行檔案一對一的使用,而是讓多個可執行檔案指向乙個庫檔案,達到共用. 宗旨:節省了記憶體空間,提高了空間利用率。
示例2
#include #include #include #include #include "hello.h"
int getvalue(char *pszval)
int printfhello()
const hello_st_api hello = ;
gcc -fpic hello.c -c生成hello.o
gcc -shared -o hello.so hello.o 生成hello.so
#include #include #include #include #include #include "hello.h"
int main(int argc, char **ar**);
handle = dlopen("/home/test/dl-api/hello.so", rtld_lazy);
if (! handle)
dlerror();
hello = dlsym(handle, "hello");
if (!hello)
if (hello && hello->printfhello)
i = hello->printfhello();
printf("%s, %d, i = %d\n", __function__, __line__, i);
if (hello && hello->getvalue)
i = hello->getvalue(psvalue);
if (hello && hello->module)
printf("%s, %d, module = %s\n", __function__, __line__, hello->module);
dlclose(handle);
return 0;
}
gcc -o test hello_dlopen.c -ldl
執行結果
printfhello, 27, hello everyone
main, 36, i = 0
getvalue, 19, pszver = 123456
main, 42, module = hello
dlopen函式詳解
linux提供了一套api來動態裝載庫。下面列出了這些api dlopen,開啟乙個庫,並為使用該庫做些準備。dlsym,在開啟的庫中查詢符號的值。dlclose,關閉庫。dlerror,返回乙個描述最後一次呼叫dlopen dlsym,或dlclose的錯誤資訊的字串。c語言使用者需要包含標頭檔案...
dlopen引數總結
void dlopen const char pathname,int mode 返回乙個void 型別的handle,否則返回null。pathname就是所要開啟的動態庫,如果這個庫宣告鏈結了其它庫,即對其它庫有依賴關係,那麼所有相關有依賴關係的庫都會被開啟,這些開啟的庫稱之為組 group m...
dlopen函式詳解
linux提供了一套api來動態裝載庫。下面列出了這些api dlopen,開啟乙個庫,並為使用該庫做些準備。dlsym,在開啟的庫中查詢符號的值。dlclose,關閉庫。dlerror,返回乙個描述最後一次呼叫dlopen dlsym,或dlclose的錯誤資訊的字串。c語言使用者需要包含標頭檔案...