Linux庫函數制作(靜態庫、動態庫)
靜態庫與動態庫
鏈接方式
鏈接分為兩種:靜態鏈接、動態鏈接
靜態鏈接:
由鏈接器在鏈接時將庫的內容加入到可執行程序中
靜態鏈接的特點是:
優點:
對運行環境的依賴性較小,具有較好的兼容性
缺點:
生成的程序比較大,需要更多的系統資源,在裝入內存時會消耗更多的時間
庫函數有了更新,必須重新編譯應用程序
動態鏈接:
連接器在鏈接時僅僅建立與所需庫函數的之間的鏈接關系,在程序運行時才將所需資源調入可執行程序
動態鏈接的特點:
優點:
在需要的時候才會調入對應的資源函數
簡化程序的升級;有着較小的程序體積
實現進程之間的資源共享(避免重復拷貝)
缺點:
依賴動態庫,不能獨立運行
動態庫依賴版本問題嚴重
/*************************************************************************
> File Name: myprintf.c
> Author: lsgxeva
> Mail: lsgxeva@163.com
> Created Time: 2017年09月28日 星期四 11時52分57秒
************************************************************************/
#include <stdio.h>
void myprintf(void)
{
printf("hello, world!\n");
}
/*************************************************************************
> File Name: myprintf.h
> Author: lsgxeva
> Mail: lsgxeva@163.com
> Created Time: 2017年09月28日 星期四 11時53分15秒
************************************************************************/
#ifndef _MYPRINTF_H_
#define _MYPRINTF_H_
extern void myprintf(void);
#endif // _MYPRINTF_H_
/*************************************************************************
> File Name: mytest.c
> Author: lsgxeva
> Mail: lsgxeva@163.com
> Created Time: 2017年09月28日 星期四 11時54分26秒
************************************************************************/
#include "myprintf.h"
int main()
{
myprintf();
return 0;
}
目錄結構
drwxr-xr-x 5 root root 94 9月 28 12:22 .
drwxr-xr-x 5 root root 54 9月 28 11:08 ..
-rw-r--r-- 1 root root 360 9月 28 11:53 myprintf.c
-rw-r--r-- 1 root root 380 9月 28 11:54 myprintf.h
-rw-r--r-- 1 root root 351 9月 28 12:22 mytest.c
drwxr-xr-x 2 root root 6 9月 28 12:24 output
drwxr-xr-x 2 root root 6 9月 28 11:56 shared
drwxr-xr-x 2 root root 6 9月 28 12:23 static
制作靜態鏈接庫
制作動態鏈接庫
解決無法打開動態庫的常用簡便方法:
聲明臨時變量環境
export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH
或者修改 /etc/ld.so.conf 文件 在其中添加庫的搜索路徑,一行一個路徑。
sudo ldconfig 更新 /etc/ld.so.cache 文件
那 ./etc/ld.so.conf 中所有路徑的庫文件都被緩存達到 /etc/ld.so.cache 中。
注意: 將生成共享庫的編譯參數-shared錯誤地用於生成可執行文件,將導致程序運行時發生段錯誤!
編譯產生動態鏈接庫,並支持 major 和 minor 版本號。
動態鏈接和靜態鏈接時,可執行文件的區別:
Linux共享對象之編譯參數fPIC
g++ -fPIC -shared test.cc -o lib.so
g++ -fPIC test.cpp -c -o test.o ld -shared test.o -o lib.so
/usr/bin/ld: test.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC test.o: could not read symbols: Bad value collect2: ld returned 1 exit status
readelf -d foo.so |grep TEXTREL
readelf -r Lib.so