在《Using the GNU Compiler Collection》gcc 4.30 中關於-lpthread的描述如下:
-pthread Add support for multithreading using the POSIX threads library. This option
sets flags for both the preprocessor and linker. It does not affect the thread
safety of object code produced by the compiler or that of libraries supplied with
it. These are HP-UX specific flags.
-ldl
#include <dlfcn.h>
dlopen(),dlclose() , dlerror() , dlsym() , the Base Definitions volume of IEEE Std 1003.1-2001, <dlfcn.h>
這些函數,動態庫的相關部分
-dl ,同樓上所說,是顯式加載動態庫的動態函數庫
在動態庫的使用程序裡面根據動態庫提供的函數接口聲明調用動態庫裡面的函數。在編寫調用動態庫的程序的makefile文件時,需要加入編譯選項-rdynamic和-ldl。 [喝小酒的網摘]http://blog.hehehehehe.cn/a/17158.htm
用nm命令查看動態庫文件提供哪些調用:
nm -D /usr/lib/libz.so
理解動態鏈接庫
在Linux的應用開發中,靜態庫和動態庫都是我們經常用到的技術,有必要對這兩個概念及其原理做一些介紹。
靜態庫
靜態庫是一些目標文件的集合,通常為後綴為.o 的文件,通過ar 工具打包而成,命名
格式為libxxx.a ,其中xxx 為給定的靜態庫文件名,如libm.a ,為數學函數庫,用戶也可以命名自己的庫。在創建可執行程序的過程中,靜態庫同時被鏈接到程序代碼,被主程序調用的函數目標文件連同主程序組合成單一的可 執行程序。靜態庫只在程序鏈接時起作用,最終的執行程序脫離靜態庫運行。
動態庫
按照其英文(shared library )也可理解為共享庫,動態庫的後綴一般為.so ,通過編譯器生成,在不同的平台有不同的生成方法,但是在Linux 平台中,其使用及工作原理是一致的。使用動態庫創建執行程序,分為兩個階段:鏈接階段,即通過ld 創建執行程序時,鏈接編輯器會在指定的動態庫中搜索、解析被主程序調用的函數及其他變量等,如引用被找到,則在執行程序的XCOFF 頭結構的loader
區域,建立包含引用的動態庫的影像,反之,如在指定的動態庫中沒有找到此引用的定義,編譯器會給出類似未定義的符號引用錯誤。這不同於靜態庫,包含引用的 目標文件並不和執行程序鏈接在一起。
另一階段為運行階段,即執行程序運行時。程序運行時,系統相關模塊將讀取定義執行程
序的XCOFF 頭結構中的信息,查找並加載相關的動態庫,假設,所有被應用的動態庫都被定位且加載後,程序將開始運行。反之,如果,被應用的動態庫丟失,則程序報錯。這 一個過程我們常稱之為動態鏈接。可以通過一個簡單的例子來分析靜態庫與動態庫的不同,假定執行程序名為a.out ,分別通過靜態庫和動態庫編譯、鏈接.對使用動態庫的程序,程序啟動後,相關的動態庫的目標代碼加載到系統內存,而且可以被其他使用此動態庫的執行程序共
享使用。這樣,在給定的時間,統一動態庫的代碼在系統中只有一份拷貝,所有使用此動態庫的程序可共享這一拷貝。動態鏈接的使用可以節省系統內存的使用,對 一些比較復雜的應用作用比較明顯,另外,執行程序代碼的減小,也可以節省磁盤空間。
加載動態鏈接庫,首先為共享庫分配物理內存,然後在進程對應的頁表項中建立虛擬頁和物理頁面之間的映射。你可以認為系統中存在一種引用計數機制, 每當一個進程加載了共享庫(在該進程的頁表中進行一次映射),引用計數加一;一個進程顯式卸載(通過dlclose等)共享庫或進程退出時,引用計數減 一,當減少到0時,系統卸載共享庫。
(1)打開動態鏈接庫:dlopen,函數原型void *dlopen (const char *filename, int flag); dlopen用於打開指定名字(filename)的動態鏈接庫,並返回操作句柄。
(2)取函數執行地址:dlsym,函數原型為: void *dlsym(void *handle, char *symbol); dlsym根據動態鏈接庫操作句柄(handle)與符號(symbol),返回符號對應的函數的執行代碼地址。
(3)關閉動態鏈接庫:dlclose,函數原型為: int dlclose (void *handle); dlclose用於關閉指定句柄的動態鏈接庫,只有當此動態鏈接庫的使用計數為0時,才會真正被系統卸載。
(4)動態庫錯誤函數:dlerror,函數原型為: const char *dlerror(void); 當動態鏈接庫操作函數執行失敗時,dlerror可以返回出錯信息,返回值為NULL時表示操作函數執行成功。