歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux編程練習(二)—— Linux下.so動態庫的建立和調用

(在Ubuntu 12.04系統下進行測試)

實現將一個自己編寫的Hello.c文件打包成libHello.so動態庫,並通過gcc編譯工具實現用一個test.c程序調用libHello.so和自定義頭文件Hello.h的過程。

具體程序代碼如下:

//Hello.h文件

include <stdio.h>
void printhello();

 

//Hello.c文件

#include <stdio.h>
void printhello()
{
  puts("Hello World!");
}

 

//test.c文件

#include <Hello.h>
int main()
{
 printhello();
 return 0;
}

 

具體操作過程:
第一步:
    將文件Hello.c編譯成一個動態庫:libHello.so,執行命令如下:

        $ gcc Hello.c -fPIC -shared -o libHello.so

    -shared: 該選項指定生成動態連接庫(讓連接器生成T類型的導出符號表,有時候也生成弱連接W類型的導出符號),不用該標志外部程序無法連接,相當於一個可執行文件;

    -fPIC:表示編譯為位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的,所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的。


第二步:
    生成Hello.c文件的動態鏈接庫libHello.so以後,直接在包含Hello.h和libHello.so文件夾底下運行如下gcc命令:

      $ gcc test.c -lHello -L. -I. -o test

 

    -L.:-L後跟連接庫的路徑,‘.’表示要連接的庫在當前目錄中;

    -I.:表示要連接的頭文件在當前目錄;

    -lHello:編譯器查找動態連接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來確定庫的名稱(即:libHello.so)。


第三步:
    執行命令“$ ldd test” 打印test可執行文件的動態庫依賴關系,結果輸出:

      linux-vdso.so.1 =>  (0x00007fff16b8a000)
      libHello.so => not found
      libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55700c000)
      /lib64/ld-linux-x86-64.so.2 (0x00007fa5573e4000)

    其中,“libHello.so => not found”表明鏈接程序找不到libHello.so文件,這是因為鏈接程序只尋找固定目錄(一般為/lib和/usr/lib),解決方法有兩種:
    方法一:把libHello.so拷貝到鏈接程序的搜索路徑目錄下(/lib或/usr/lib)。
    方法二:設置環境變量LD_LIBRARY_PATH,增加當前路徑到該變量中。
        配置環境變量的方法為:

 


          LD_LIBRARY_PATH = LD_LIBRARY_PATH:"當前路徑名";
          export LD_LIBRARY_PATH

    這裡采用第一種解決方法,再次執行“$ ldd test”,此時顯示:


        linux-vdso.so.1 =>  (0x00007fff6c7d7000)
        libHello.so => /lib/libHello.so (0x00007f818dce3000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f818d923000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f818defd000)


    libHello.so=>後有值,說明查找動態庫成功。
    執行“./test”命令,正確輸出相應結果。

Copyright © Linux教程網 All Rights Reserved