Liunx下靜態庫和動態庫的創建與使用

  1. 靜態庫
    假如我們有如下加減功能的文件:
// add.h
#ifndef __ADD_H__
#define __ADD_H__

int Add(int a, int b);

#endif // __ADD_H__
// add.c
#include "add.h"

int Add(int a, int b)
{
	return a + b;
}
// sub.h
#ifndef __SUB_H__
#define __SUB_H__

int Sub(int a, int b);

#endif // __SUB_H__
// sub.c
#include "sub.h"

int Sub(int a, int b)
{
	return a - b;
}

有個應用想利用加減函數:

// main.c
#include <stdio.h>
#include "add.h"
#include "sub.h"

int main()
{
	int a = 6;
	int b = 3;

	printf("a + b = %d, a - b = %d\n", Add(a, b), Sub(a, b));

	return 0;
}

下面開始編譯.a靜態庫,再鏈接到main.c中:
// 生成obj文件
1.gcc -c *.c
// 刪除多餘的main.o
2.rm main.o
// 生成cal1靜態庫
3.ar -rc libcal1.a *.o
// 刪除過程中的.o文件
4. rm *.o
// 鏈接libcal1.a到main.c (ai)表示音標,爲了區分I與小L。因爲網頁上I(ai),l(小L)根本看不出區別。。。實際鏈接是不要加音標哈。test表示生成文件的名字,可修改。
5.gcc -o test main.c -I(ai) -L libcal1.a
然後就可以執行test程序了
6. ./test

以上是庫、頭文件、引用程序都在同一目錄的情況下。假若是這種結構呢?
----libcal1
--------include
------------add.h
------------sub.h
--------lib
------------libcal1.a
----main.c
我們如何執行第5步的鏈接過程?
// -I(ai)指定頭文件目錄 -L 指定庫文件目錄 -l(小L)指定庫名,注意小L後跟的庫名要去掉lib與.a
gcc -o test main.c -I(ai) ./libcal/include -L ./libcal/lib -l(小L) cal1

  1. 動態庫
    假如我們有如下乘除功能的文件:
// mul.h
#ifndef __MUL_H__
#define __MUL_H__

int Mul(int a, int b);

#endif // __MUL_H__
// mul.c
#include "mul.h"

int Mul(int a, int b)
{
	return a * b;
}
// div.h
#ifndef __DIV_H__
#define __DIV_H__

int Div(int a, int b);

#endif // __DIV_H__
// div.c
#include <stdio.h>
#include "div.h"

int Div(int a, int b)
{
	if (0 == b) {
		printf("error! b is zero\n");
		return 0;
	}

	return a / b;
}

有個應用想利用乘除函數:

// main.c
#include <stdio.h>
#include "mul.h"
#include "div.h"

int main()
{
	int a = 6;
	int b = 3;
	printf("a x b = %d, a / b = %d\n", Mul(a, b), Div(a, b));

	return 0;
}

下面開始編譯.so動態庫,再鏈接到main.c中:
// 生成obj文件
1.gcc -c *.c
// 刪除多餘的main.o
2.rm main.o
// 生成cal2動態庫
3.gcc -shared -o libcal2.so *.o
// 刪除過程中的.o文件
4. rm *.o
// 鏈接libcal1.a到main.c (ai)表示音標,爲了區分I與小L。因爲網頁上I(ai),l(小L)根本看不出區別。。。實際鏈接是不要加音標哈。test表示生成文件的名字,可修改。
5.gcc -o test main.c -I(ai) -L libcal2.so
然後就可以執行test程序了
6. ./test

哈哈,然後就報錯了。因爲動態庫需要動態運行時要加載所需的庫,所以我們要指定所使用的動態庫路徑。
方法1:將編譯好的libcal2.so放到/usr/lib中。比較暴力。。。
方法2:添加配置文件。vim /etc/ld.so.conf.d/mycal2.conf。 將libcal2.so的絕對路徑寫到此文件中。再調用ldconfig重新加載配置。大功告成。./test完美運行。
假若.h,.so與main.c不在同一目錄下如何鏈接呢?方法與靜態庫一樣,使用-I(ai)指定頭文件目錄,-L指定庫文件目錄,-l(小L)指定庫名。同樣需要去掉lib與.so(栗子:libcal2.so —> cal2)。
另外-L指定的庫目錄中.a.so同時存在。優先選擇.so進行鏈接。若想用.a進行鏈接gcc需要加-static參數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章