In life, as in whist, hope nothing from the way card may be dealt to you. Play the card, whatever they be, to the best of your skill.-------人生如牌戲,別希望可以拿到什麼樣的牌。 不管拿到什麼牌,用盡你的技巧來打好牌
文章目錄
1,回顧知識及準備工作
小黑在之前寫了關於編譯過程 以及 靜態庫與動態庫的區別 的博客,需要回顧的碼友可以移步:
https://blog.csdn.net/weixin_46027505/article/details/105222904
https://blog.csdn.net/weixin_46027505/article/details/105223091
在製作庫之前我們先建下面的目錄結構:
- 第一個文件夾用來生成動態庫
- 第二個文件夾用來生成靜態庫
- 第三個文件夾用來模擬我們日常調用庫,其中lib用來存放生成好的靜態庫和動態庫
下面給出add.c, head.c, sub.c 的代碼:
add.c
int add(int a, int b)
{
return a +b;
}
head.h
#ifndef _HEAD_H_
#define _HEAD_H_
extern int add(int a,int b);
extern int sub(int a,int b);
#endif
sub.c
int sub(int a, int b)
{
return a - b;
}
然後我們在xuxiaohei下創建main.c來調用函數sub和add
#include<stdio.h>
#include "head.h"
int main(void)
{
printf("sum = %d\n",add(5,3));
printf("sub = %d\n",sub(5,3));
return 0;
}
2,靜態庫
2.1 靜態庫的生成
- 我們使用
gcc -c add.c
gcc -c sub.c
ar -crs libmystaticku.a add.o sub.o
- 生成靜態庫
- 然後將head.h和靜態庫複製到lib下
2.2 編譯過程中靜態庫的使用
- gcc main.c -o myapp -I ./lib -lmystatic -L ./lib -static
- 其中第一個是大寫的 i ,後面是頭文件路徑
- -lmystatic 是小寫的L + 去掉lib和.a剩下的
- -L 後面跟庫所在路徑
2.2 運行程序時靜態庫的使用
因爲靜態庫在靜態鏈接庫(靜態編譯)的時候,已經加載進myapp,所以可以直接執行,而後面的動態庫就要複雜一些。
- 然後查看靜態庫大小和信息,可以後面與動態庫比較
如果想要可執行文件 myapp 更小,可以
strip myapp
2,動態庫
爲了不混淆,我們將上面的myapp刪除,然後用動態鏈接重新生成myapp
2.1 動態庫的生成
gcc -fpic -shared add.c sub.c -o libmyshared.so
- 然後複製到xuxiaohei的lib下
2.2 編譯過程中動態庫的使用
這裏和靜態庫一樣,只是少了-static
2.3 運行程序時動態庫的使用
出現問題
這是因爲程序運行時沒有找到動態鏈接庫造成的。程序編譯時鏈接動態庫和運行時使用動態鏈接庫的概念是不同的,在運行時,程序鏈接的動態鏈接庫需要在系統目錄下才行。
Linux下在運行程序時,會默認到 /lib、/lib64、/usr/lib以及LD_LIBRARY_PATH環境變量指定的路徑下查找所需的動態庫下查 找所需的動態庫文件,如果沒有則拋錯。而這時libmycshared.so並不在系統庫路徑下,所以會出錯
可以使用
ldd myapp查看具體錯誤
解決方案
方法一:
在linux下最方便的解決方案是拷貝libshared.so到絕對目錄 /lib 下, 但是,要是超級用戶纔可以,因此要使用sudo。就可以生成可執行程序了
方法二:
將動態鏈接庫的目錄放到程序搜索路徑中,可以將庫的路徑加到環境變量LD_LIBRARY_PATH中實現:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/xuxiaohei/test/xuxiaohei/lib
執行此命令後也可以生成可執行程序