轉載:http://blog.csdn.net/acb0y/article/details/6553051
1、動態庫*.so的編譯
這裏我們用到4個文件,它們分別爲:SoDemoTest.h、one.cpp、two.cpp、three.cpp。它們的內容如下:
SoDemoTest.h
#ifndef __SO_DEMO_TEST_HEADER__
#define __SO_DEMO_TEST_HEADER__
#include <iostream>
using namespace std;
void one();
void two();
void three();
#endif
one.cpp
#include "SoDemoTest.h"
void one()
{
cout << "call one() function." << endl;
}
two.cpp
#include "SoDemoTest.h"
void two()
{
cout << "call two() function." << endl;
}
three.cpp
#include "SoDemoTest.h"
void three()
{
cout << "call three() function." << endl;
}
將這幾個文件編譯成動態庫libtest.so。編譯命令如下:
$g++ one.cpp two.cpp three.cpp -fPIC -shared -o libtest.so
2、動態庫的鏈接
在上面的部分,我們已經生成了一個libtest.so的動態鏈接庫,現在我們用一個程序來調用這個動態鏈接庫。
文件名爲:main.cpp
#include "SoDemoTest.h"
int main()
{
one();
two();
three();
return 0;
}
將main.cpp與libtest.so鏈接成一個可執行文件main。命令如下:
$ g++ main.cpp -L. -ltest -o main
測試可執行程序main是否已經鏈接的動態庫libtest.so,如果列出了libtest.so,那麼就說明正常鏈接了。可以執行以下命令:
$ldd main
執行main可以看看main是否調用了動態鏈接庫中的函數。
3、編譯參數
-shared 該選項指定生成動態連接庫(讓連接器生成T類型的導出符號表,有時候也生成弱連接W類型的導出符號),不用該標誌外部程序無法連接。相當於一個可執行文件。
-fPIC:表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的。
-L.:表示要連接的庫在當前目錄中。
-ltest:編譯器查找動態連接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來確定庫的名稱
LD_LIBRARY_PATH:這個環境變量指示動態連接器可以裝載動態庫的路徑。
4、注意的問題
調用動態庫的時候有幾個問題會經常碰到,有時,明明已經將庫的頭文件所在目錄 通過 “-I” include進來了,庫所在文件通過 “-L”參數引導,並指定了“-l”的庫名,但通過ldd命令察看時,就是死活找不到你指定鏈接的so文件,這時你要作的就是通過修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件來指定動態庫的目錄。通常這樣做就可以解決庫無法鏈接的問題了。
參考:
http://blog.sina.com.cn/s/blog_54f82cc20101153x.html
http://www.cnblogs.com/tzhangofseu/archive/2011/11/15/2249585.html