關於linux下GCC生成共享庫(動態鏈接庫)的探究


下面列出了我在對共享庫(動態鏈接庫)編寫以及使用時遇到的幾個簡單問題進行探究和解答:

參考文檔:http://www.cnblogs.com/likwo/archive/2012/05/09/2492225.html

 

1.靜態庫、動態鏈接庫、共享庫有什么區別?

  靜態庫(windows下為.lib,linux下為.a)是在程序編寫前就編譯到目標程序中了,而動態鏈接庫(windows下為.dll)可以在程序執行的任何時候被動態加載。共享庫(linux下為.so)是在程序啟動的時候加載到程序中。

1).動態鏈接庫和共享庫之間的區別是什么?

  我個人認為可以將它們看做是是相同的。如果真的希望了解它們構成上的區別,可以參考這一篇文章:http://www.cnblogs.com/likwo/archive/2012/05/09/2492225.html

 

2.為什么要用.so文件?

  1.由於共享庫能被應用程序動態載入內存。所以,應用程序可以在需要時才將.so載入到內存中,這讓程序的可維護性變得很高。比如QQ的視頻功能需要升級,那么負責編寫QQ的程序員不必將QQ所有代碼都重寫,只需將視頻功能相關的.so文件重寫即可。

  2.生成的.so文件可以認為是一個函數,其他程序就可以在它們的代碼中直接調用這些函數來完成相同的工作(相對於其他直接給出源碼的函數來講,這應該是所謂的閉源)。這樣的庫(代碼)可以重復調用,從而減小了代碼的編寫量,實現了代碼的模塊化。

 

3.如何在生成.so/.dll文件?

  1.關於生成.dll文件,可以參考我的這一篇簡短的介紹:http://www.cnblogs.com/vincentX/p/4798830.html

  2.生成.so文件:

  舉一個簡單的例子,我們來實現兩個數相加的功能:

  1.首先新建2個文件,分別命名為test.h test.c tmp.c

  2.將如下代碼寫入test.h文件中:

1 int add(int, int);

  3.將如下代碼寫入test.c文件中:

1 #include "test.h"
2 
3 int add(int a, int b) {
4     return a + b;
5 }

  4.將test.c編譯成.so文件,bash命令如下:

1 gcc test.c -shared -fPIC -o test.so

    shared是生成共享庫,-fPIC是聲明使用位置無關代碼。關於為什么需要加入-fPIC,我會在后面解答。

    這時候便在當前目錄下生成了一個.so文件。

  5.接下來將如下代碼寫入tmp.c文件中:

1 #include <stdio.h>
2 #include "test.h"
3 
4 int main() {
5     printf("Hello world\n");
6     printf("%d\n", add(2, 3));
7     return 0;
8 }

 

  6.編譯tmp.c:

1 gcc tmp.c -o tmp ./test.so

  至此我們可以./tmp來測試一下是否正常使用剛剛寫好的.so文件了。執行一下tmp文件: 

1 ./tmp

  結果如下:

1 Hello world
2 5

 

  說明生成的共享庫可以使用了。

  我們來做一個小實驗:此時把剛剛生成的.so文件刪除掉,會有什么樣的情況發生呢?

1 rm test.so
2 ./tmp

  此時會返回這樣一個錯誤信息:

1 ./tmp: error while loading shared libraries: ./test.so: cannot open shared object file: No such file or directory

  找不到tmp中包含的共享庫test.so。同時可以解釋為,可執行文件的確是在運行前調用的.so文件,(因為此時的hello world也沒有被輸出)。當我們重新將test.so編譯出來以后再執行tmp,便仍然可以正常運行。

 

4.關於-fPIC?

  在linux下制作共享庫的“標准做法”是將.so文件編譯成位置無關代碼,然后生成.so文件。因此我在思考:-fPIC是否是必需的?因為不添加-fPIC的時候也可以正常運行。

  關於-fPIC的詳細解釋可以參見:http://www.cnblogs.com/cswuyg/p/3830703.html

 

 

轉載請聲明出處,謝謝合作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM