日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux下gcc编译生成动态链接库*.so文件并调用它

發(fā)布時(shí)間:2024/4/17 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下gcc编译生成动态链接库*.so文件并调用它 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

動(dòng)態(tài)庫(kù)*.so在linux下用c和c++編程時(shí)經(jīng)常會(huì)碰到,最近在網(wǎng)站找了幾篇文章介紹動(dòng)態(tài)庫(kù)的編譯和鏈接,總算搞懂了這個(gè)之前一直不太了解得東東,這里做個(gè)筆記,也為其它正為動(dòng)態(tài)庫(kù)鏈接庫(kù)而苦惱的兄弟們提供一點(diǎn)幫助。
1、動(dòng)態(tài)庫(kù)的編譯

下面通過(guò)一個(gè)例子來(lái)介紹如何生成一個(gè)動(dòng)態(tài)庫(kù)。這里有一個(gè)頭文件:so_test.h,三個(gè).c文件:test_a.c、test_b.c、test_c.c,我們將這幾個(gè)文件編譯成一個(gè)動(dòng)態(tài)庫(kù):libtest.so。

//so_test.h:
#include "stdio.h"
void test_a();
void test_b();
void test_c();

//test_a.c:
#include "so_test.h"
void test_a()
{
??printf("this is in test_a...\n");
}


//test_b.c:
#include "so_test.h"
void test_b()
{
??printf("this is in test_b...\n");
}



//test_c.c:
#include "so_test.h"
void test_c()
{
??printf("this is in test_c...\n");
}
將這幾個(gè)文件編譯成一個(gè)動(dòng)態(tài)庫(kù):libtest.so
$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

2、動(dòng)態(tài)庫(kù)的鏈接
在1、中,我們已經(jīng)成功生成了一個(gè)自己的動(dòng)態(tài)鏈接庫(kù)libtest.so,下面我們通過(guò)一個(gè)程序來(lái)調(diào)用這個(gè)庫(kù)里的函數(shù)。程序的源文件為:test.c。

test.c:
#include "so_test.h"
int main()
{
test_a();
test_b();
test_c();
return 0;
}
將test.c與動(dòng)態(tài)庫(kù)libtest.so鏈接生成執(zhí)行文件test:
$ gcc test.c -L. -ltest -o test
測(cè)試是否動(dòng)態(tài)連接,如果列出libtest.so,那么應(yīng)該是連接正常了
$ ldd test
執(zhí)行test,可以看到它是如何調(diào)用動(dòng)態(tài)庫(kù)中的函數(shù)的。
3、編譯參數(shù)解析
最主要的是GCC命令行的一個(gè)選項(xiàng):
-shared該選項(xiàng)指定生成動(dòng)態(tài)連接庫(kù)(讓連接器生成T類型的導(dǎo)出符號(hào)表,有時(shí)候也生成弱連接W類型的導(dǎo)出符號(hào)),不用該標(biāo)志外部程序無(wú)法連接。相當(dāng)于一個(gè)可執(zhí)行文件

-fPIC:表示編譯為位置獨(dú)立的代碼,不用此選項(xiàng)的話編譯后的代碼是位置相關(guān)的所以動(dòng)態(tài)載入時(shí)是通過(guò)代碼拷貝的方式來(lái)滿足不同進(jìn)程的需要,而不能達(dá)到真正代碼段共享的目的。

-L.:表示要連接的庫(kù)在當(dāng)前目錄中

-ltest:編譯器查找動(dòng)態(tài)連接庫(kù)時(shí)有隱含的命名規(guī)則,即在給出的名字前面加上lib,后面加上.so來(lái)確定庫(kù)的名稱

LD_LIBRARY_PATH:這個(gè)環(huán)境變量指示動(dòng)態(tài)連接器可以裝載動(dòng)態(tài)庫(kù)的路徑。

當(dāng)然如果有root權(quán)限的話,可以修改/etc/ld.so.conf文件,然后調(diào)用 /sbin/ldconfig來(lái)達(dá)到同樣的目的,不過(guò)如果沒(méi)有root權(quán)限,那么只能采用輸出LD_LIBRARY_PATH的方法了。

4、注意

調(diào)用動(dòng)態(tài)庫(kù)的時(shí)候有幾個(gè)問(wèn)題會(huì)經(jīng)常碰到,有時(shí),明明已經(jīng)將庫(kù)的頭文件所在目錄 通過(guò) “-I” include進(jìn)來(lái)了,庫(kù)所在文件通過(guò) “-L”參數(shù)引導(dǎo),并指定了“-l”的庫(kù)名,但通過(guò)ldd命令察看時(shí),就是死活找不到你指定鏈接的so文件,這時(shí)你要作的就是通過(guò)修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件來(lái)指定動(dòng)態(tài)庫(kù)的目錄。通常這樣做就可以解決庫(kù)無(wú)法鏈接的問(wèn)題了。

在linux下可以用export命令來(lái)設(shè)置這個(gè)值,在linux終端下輸入:
export LD_LIBRARY_PATH=/opt/au1200_rm/build_tools/bin: $LD_LIBRARY_PATH:   
然后再輸入:export   
即會(huì)顯示是否設(shè)置正確   
export方式在重啟后失效,所以也可以用 vim /etc/bashrc ,修改其中的LD_LIBRARY_PATH變量。   
例如:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/au1200_rm/build_tools/bin。

轉(zhuǎn)載于:https://www.cnblogs.com/huangxinzhen/p/4047051.html

總結(jié)

以上是生活随笔為你收集整理的Linux下gcc编译生成动态链接库*.so文件并调用它的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。