C语言 共享库(动态库)制作
文章目錄
-
-
- 共享庫簡介
- 共享庫制作
-
- 代碼實現
- 創建共享庫
- 鏈接使用共享庫
- 小結
-
?
共享庫簡介
共享庫的本質就是將多個目標文件打包成一個文件。鏈接共享庫就是在可執行文件中調用共享庫中函數的指令處插入一些指令,在運行時通過執行這些指令來完成加載共享庫以及計算出所調函數入口地址的動作。使用共享庫的可執行文件占用磁盤和內存相對于靜態庫要小。共享庫中的代碼一旦被修改,只要函數接口不變,無需重新鏈接。使用共享庫的可執行文件在運行時,需要依賴共享庫。一旦共享庫被刪除,則可執行文件無法運行。
共享庫的文件形式為:lib<庫名>.so
共享庫制作
代碼實現
假如我們制定一個數學操作的共享庫,在同一個文件夾下,有如下文件:
– add.c
– add.h
– sub.c
– sub.h
add.c為加法操作實現,sub.c為減法操作實現。
代碼如下:
add.h
#ifndef C_ADD_H #define C_ADD_Hint add(int a, int b);#endif //C_ADD_H- ?
add.c
#include "add.h"int add(int a, int b) {return a + b; }- ?
sub.h
#ifndef C_SUB_H #define C_SUB_Hint sub(int a, int b);#endif //C_SUB_H- ?
sub.c
#include "sub.h"int sub(int a, int b) {return a - b; }- ?
創建共享庫
首先我們將源代碼編譯為目標文件:
gcc命令需要加-fPIC選項,將目標文件編譯為位置無關碼,動態庫內部跳轉都是通過全局映射表來將程序中的虛擬地址找到動態庫的實際地址,來進行調用的。
gcc -fPIC -c add.c sub.c
執行完畢后會生產add.o和sub.o文件。
然后使用gcc的-shared選項來表明創建一個共享庫:
gcc -shared -o libmymath.so sub.o add.o
執行完后,會創建一個libmymath.so文件。
鏈接使用共享庫
我們為了使用上面的共享庫,我們在如上相同文件夾下,創建一個main.c文件:
– add.c # 加法實現
– add.h # 加法頭文件
– sub.c # 減法實現
– sub.h # 減法頭文件
– libmymath.so # 共享庫文件
– main.c # 入口主程序
main.c
#include <stdio.h> #include "add.h" #include "sub.h"int main(void) {int a = 20;int b = 10;printf("%d+%d=%d\n", a, b, add(a, b));printf("%d-%d=%d\n", a, b, sub(a, b));return 0; }- ?
我們使用#include預處理指令包含了sub.h和add.h頭文件,來使用我們制作的mymath共享庫。
如果我們直接gcc -o main main.c肯定會出錯,因為編譯器不知道add.h和sub.h是哪里來的,也不知道add和sub函數的定義在哪里。
所以我們需要使用-l選項,讓編譯器鏈接到我們制作的共享庫:
gcc -o main -lmymath main.c
執行上面的命令發現還是會報錯,是因為編譯器默認查找的/usr/lib;/usr/local/lib系統文件夾中的庫。而非我們的制作的共享庫存放地址,除非將你制作的libmymath.a放到上面的lib文件夾中,那么執行上面的命令就不會有問題。如果不在上述文件夾中,則需要使用-L來指定附加庫文件搜索路徑。
此處我的libmymath.a在當前目錄,所以執行:
gcc -o main -lmymath -L./ main.c
sudo cp libmymath.so /lib
把libmymath.so 拷貝到/lib路徑下,以便可執行文件運行后加載庫。
注意:gcc的-l選項后面跟的庫名,只需要指定除去lib和.so后綴的中間的實際命名就可以了,編譯器會自動按照lib<庫名>.so規則來搜索庫文件。
如果預處理指令#include包含的頭文件不在當前目錄下,則需要在gcc的時候,通過-I選項來指定頭文件附加搜索路徑。
此時在當前目錄生成了main的可執行文件。
運行得到如下:
- ?
可執行文件在運行期需加載動態庫文件,所以如果動態庫被刪除,那么執行文件會報錯。
至此,從動態庫的制作到鏈接使用就結束了。
小結
創建動態庫gcc編譯目標文件需使用-fpic選項來為目標文件生成位置無關碼:
gcc -fPIC -c xx1.c xx2.c
將多個目標文件打包成一個libxx.so文件:
gcc -shared -o libxx.so xx1.o xx2.o
在可執行程序編譯鏈接共享庫,和鏈接靜態庫是一樣的:
gcc -l<庫名> -L<庫附加搜索路徑> xx.c
總結
以上是生活随笔為你收集整理的C语言 共享库(动态库)制作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言 静态库制作(亲测可行)
- 下一篇: C语言: 函数调用的开销