動態庫(.so)的製作

擴展:

  linux gcc命令

  1. 描述:
    a. 動態庫也叫共享庫
    b. 動態庫把對一些庫函數的鏈接載入推遲到程序運行的時期(runtime)。
    c. 可以實現進程之間的資源共享。
    d. 將一些程序升級變得簡單。
    e. 甚至可以真正做到鏈接載入完全由程序員在程序代碼中控制。
    f. 動態鏈接庫的名字形式爲 “libxxx.so” 後綴名爲 “.so”。
    g. windows共享庫是以 .dll 爲後綴的文件。
  2. 特點:
    a. 在程序編譯時並不會被鏈接到目標代碼中,而是在程序運行是才被載入,系統會在動態庫環境變量所指定的目錄下去找對應名字的動態庫。
    b. 在程序運行時還需要動態庫存在,
    c. 代碼體積較小
    d. 不同的應用程序如果調用相同的庫,那麼在內存裏只需要有一份該共享庫的實例。
  3. 創建動態庫(測試例程在結尾):
    a. 將庫源文件編譯成.o的目標文件–> gcc -c mylib.c -o mylib.o //-fPIC 創建與地址無關的編譯程序
    b. 將.o文件製作成動態庫文件 --> gcc [-shared] -fPIC -o libmylib.so mylib.o //這裏的-shared是默認的,不寫也可以
    c. 編譯test.c 同時鏈接製作的動態庫 --> gcc -o test test.c -L. -lmylib // -L庫的路徑 -l庫名
  4. 使用ldd命令查看可執行程序所依賴的動態庫:
    可以看到libmylib.so動態庫沒有找到,需要配置該動態庫的路徑。
      
  5. 配置該動態庫路徑位置路徑 :
    動態庫默認路徑爲/lib 或者 /usr/lib,有以下方法配置。
    a. 方法1:將libmylib.so動態庫放到/lib 或者 /usr/lib目錄下。
    b. 方法2:將動態庫所在的路徑加入配置文件: /etc/ld.so.conf 的後面,如下:
     打開文件: sudo vim /etc/ld.so.conf
     使用pwd命令查看當前libmylib.so動態庫所在的路徑
      
     ld.so.conf文件裏添加libmylib.so動態庫的路徑,如下一行:
       /media/sf_VirtualBox_share/庫的製作
      
     運行動態鏈接庫管理命令:sudo ldconfig
    c. 方法3:將動態庫所在的路徑臨時加入到環境變量中: LD_LIBRARY_PATH
      執行下面的命令:
      export LD_LIBRARY_PATH=./
      ./表示將當前路徑臨時加入到環境變量中,也就是這個路徑–>
         /media/sf_VirtualBox_share/庫的製作
      注意: 這個方法只對當前使用的shell終端有效。

  6. 再次使用ldd命令查看可執行文件所依賴的動態庫
    可以看到libmylib.so庫找到了。
      
  7. 注意:
      將程序與動態庫建立關係時,-L參數用於指定動態庫的具體路徑。-L.表示所要鏈接的庫在當前目錄下。而建立鏈接後需要把動態庫放到指定的位置,這樣在可執行程序運行時能正確加載動態庫。
  8. ldconfig命令
      ldconfig 命令的用途,主要是在默認搜尋目錄 (/lib和/usr/lib) 以及動態庫配置文件/etc/ld.so.conf內所列的目錄下,搜索出可共享的動態鏈接庫,進而創建出動態裝入程序 (ld.so) 所需的連接和緩存文件.緩存文件默認爲 /etc/ld.so.cache,此文件保存已排好序的動態鏈接庫名字列表。
  9. 動態庫與靜態庫混合連接
       如果只使用–shared(默認選項)會造成所有的庫都使用動態鏈接的方式。這時候需要使用 - Wl,option將option作爲一個選項傳遞給鏈接器,鏈接器就可以讓後面的庫進行不同方式的鏈接。比如 gcc -L. -o test test.c -Wl,-Bstatic -lmystaticlib -Wl,-Bdynamic -lmysharelib。這裏需要保證動態鏈接放在後面,以讓動態庫(如標準庫)能在默認的共享庫路徑去尋找共享庫。也可以寫成 gcc -L. -o test test.c -Wl,-Bdynamic -lmysharelib -Wl,-Bstatic -lmystaticlib -Wl,-Bdynamic
  10. 測試例程:
    mylib.c 文件
 	int myplus(int a,int b);
	int mysub(int a,int b);
	int myplus(int a,int b)
	{
		return a + b;
	}
	int mysub(int a,int b)
	{
		return a - b;
	}

   test.c 文件

	#include <stdio.h>
	int myplus(int a,int b);
	extern int mysub(int a,int b);
	extern int main(void)
	{
		int a,b;
		printf("請輸入a和b:");
		scanf("%d%d",&a,&b);
		printf("%d + %d = %d\n",a,b,myplus(a,b));
		printf("%d - %d = %d\n",a,b,mysub(a,b));
		return 0;
	}
參考:

  ldconfig及LD_LIBRARY_PATH

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章