如何在在動(dòng)態(tài)鏈接庫(kù)中調(diào)用外部函數(shù)?
大家好,我是一個(gè)動(dòng)態(tài)鏈接庫(kù)!
這個(gè)名字,相信你一定早就如雷貫耳了。
在計(jì)算機(jī)早期時(shí)代,由于內(nèi)存資源緊張,我可是發(fā)揮了重大的作用!
不論是在 Windows 系統(tǒng)中,還是在 Unix 系列平臺(tái)上,到處都能見(jiàn)到我的身影,因?yàn)槲夷転榇蠹夜?jié)省很多資源啊,資源就是人民幣!
愉快的玩耍
比如:我的主人編寫(xiě)了這么一段簡(jiǎn)單的代碼:
# 文件:lib.c
#include <stdio.h>
int func_in_lib(int k)
{
printf("func_in_lib is called ");
return k + 1;
}
只要用如下命令來(lái)編譯,我就誕生出來(lái)了 lib.so,也就是一個(gè)動(dòng)態(tài)鏈接庫(kù):
$ gcc -m32 -fPIC --shared -o lib.so lib.c
這個(gè)時(shí)候,主人隨便把我丟給誰(shuí),我都可以為他服務(wù),只要他調(diào)用我肚子里的這個(gè)函數(shù) func_in_lib 就可以了。
雖然目前你看到我提供的這個(gè)函數(shù)很簡(jiǎn)單,但是道理都是一樣的,后面如果有機(jī)會(huì),我就在這個(gè)函數(shù)里來(lái)計(jì)算機(jī)器人的運(yùn)動(dòng)軌跡,給你瞧一瞧!
例如:張三今天寫(xiě)了一段代碼,需要調(diào)用我的這個(gè)函數(shù)。
張三這個(gè)人比較喜歡騷操作,明明他在編譯可執(zhí)行程序的時(shí)候,把我動(dòng)態(tài)鏈接一下就可以了,就像下面這樣:
$ gcc -m32 -o main main.c ./lib.so
但是張三偏偏不這么做,為了炫技,他選擇使用 dlopen 動(dòng)態(tài)加載的方式,來(lái)把我從硬盤(pán)上加載到進(jìn)程中。
咱們來(lái)一起圍觀一下張三寫(xiě)的可執(zhí)行程序代碼:
# 文件:main.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
typedef int (*pfunc)(int);
int main(int argc, char *agv[])
{
int a = 1;
int b;
// 打開(kāi)動(dòng)態(tài)庫(kù)
void *handle = dlopen("./lib.so", RTLD_NOW);
if (handle)
{
// 查找動(dòng)態(tài)庫(kù)中的函數(shù)
pfunc func = (pfunc) dlsym(handle, "func_in_lib");
if (func)
{
b = func(a);
printf("b = %d ", b);
}
else
{
printf("dlsym failed! ");
}
dlclose(handle);
}
else
{
printf("dlopen failed! ");
}
return 0;
}
從代碼中可以看到,張三預(yù)先知道我肚子里的這個(gè)函數(shù)名稱(chēng)是 func_in_lib,所以他使用了系統(tǒng)函數(shù) dlsym(handle, "func_in_lib"); 來(lái)找到這個(gè)函數(shù)在內(nèi)存中的加載地址,然后就可以直接調(diào)用這個(gè)函數(shù)了。
張三編譯得到可執(zhí)行文件 main 之后,執(zhí)行結(jié)果完全正確,很開(kāi)心!
悲從中來(lái)
可是有一天,我遇到一件煩人的事情,我的主人說(shuō):你這個(gè)服務(wù)函數(shù)的計(jì)算過(guò)程太單調(diào)了,給你找點(diǎn)樂(lè)子,你在執(zhí)行的時(shí)候啊,到其他一個(gè)外部模塊里調(diào)用一個(gè)函數(shù)。
話(huà)剛說(shuō)完,就丟給我一個(gè)函數(shù)名:void func_in_main(void);。
也就是說(shuō),我需要在我的服務(wù)函數(shù)中,去調(diào)用其他模塊里的函數(shù),就像下面這樣:
#include <stdio.h>
// 外部函數(shù)聲明
void func_in_main(void);
int func_in_lib(int k)
{
printf("func_in_lib is called ");
// 調(diào)用外部函數(shù)
func_in_main();
return k + 1;
}
那么這個(gè)函數(shù)在哪里呢?天哪,我怎么知道這個(gè)函數(shù)是什么鬼?怎么才能找到它藏在內(nèi)存的那個(gè)角落(地址)里?
不管怎么樣,主人修改了代碼之后,還是很順利的把我編譯了出來(lái):
$ gcc -m32 -fPIC --shared -o lib.so lib.c
編譯指令完全沒(méi)有變化。
因?yàn)槲覂H僅是一個(gè)動(dòng)態(tài)鏈接庫(kù),這個(gè)時(shí)候即使我不知道 func_in_main 函數(shù)的地址,也是可以編譯成功的。
只不過(guò)我要把這個(gè)家伙標(biāo)記一下:誰(shuí)要是想使用我,就必須告訴我這個(gè)家伙的地址在哪里!,否則就別怪我耍賴(lài)。
發(fā)表評(píng)論
登錄
手機(jī)
驗(yàn)證碼
立即登錄即可訪(fǎng)問(wèn)所有OFweek服務(wù)
還不是會(huì)員?免費(fèi)注冊(cè)
忘記密碼請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
圖片新聞
-

落地?zé)o錫!京東首個(gè)物流機(jī)器人超級(jí)工廠來(lái)了
-

OpenAI發(fā)布的AI瀏覽器,市場(chǎng)為何反應(yīng)強(qiáng)烈?
-

馬云重返一線(xiàn)督戰(zhàn),阿里重啟創(chuàng)始人模式
-

機(jī)器人奧運(yùn)會(huì)戰(zhàn)報(bào):宇樹(shù)機(jī)器人摘下首金,天工Ultra搶走首位“百米飛人”
-

存儲(chǔ)圈掐架!江波龍起訴佰維,索賠121萬(wàn)
-

長(zhǎng)安汽車(chē)母公司突然更名:從“中國(guó)長(zhǎng)安”到“辰致科技”
-

豆包前負(fù)責(zé)人喬木出軌BP后續(xù):均被辭退
-

字節(jié)AI Lab負(fù)責(zé)人李航卸任后返聘,Seed進(jìn)入調(diào)整期
最新活動(dòng)更多
-
6月30日立即申請(qǐng)?jiān)囉?> 【免費(fèi)試用】旭之源工業(yè)電源一一機(jī)器人的穩(wěn)定“心臟“
-
精彩回顧立即查看>> 【限時(shí)免費(fèi)】物理場(chǎng)仿真助力生物醫(yī)學(xué)領(lǐng)域技術(shù)創(chuàng)新
-
精彩回顧立即查看>> 【直播】 智測(cè)未來(lái)·2026海克斯康春季產(chǎn)品創(chuàng)新日
-
精彩回顧立即查看>> 【線(xiàn)下論壇】新唐科技×芯唐南京 2026 年度研討會(huì)
-
精彩回顧立即查看>> OFweek 2026(第十五屆)中國(guó)機(jī)器人產(chǎn)業(yè)大會(huì)
-
精彩回顧立即查看>> 維科杯· OFweek 2025中國(guó)機(jī)器人行業(yè)年度評(píng)選
推薦專(zhuān)題
-
2 華為,重大突破!
- 1 人形機(jī)器人“第一股”來(lái)了!宇樹(shù)科技即將上會(huì)
- 2 全球股市陷AI獨(dú)大結(jié)構(gòu)性瘋狂
- 3 AI狂歡遇上油價(jià)破百,全球股市還能漲多久? | 產(chǎn)聯(lián)看全球
- 4 DeepSeek融資500億,梁文鋒難逃資本局
- 5 谷歌2026 I/O大會(huì)完整回顧:模型依然重要,但智能體正在接管一切
- 6 全球資本,重倉(cāng)中國(guó)機(jī)器人
- 7 Figure AI 交付突破350臺(tái),陪跑特斯拉會(huì)迎來(lái)iPhone 時(shí)刻嗎?
- 8 Anthropic發(fā)布2028年全球AI領(lǐng)導(dǎo)力的兩種情景報(bào)告
- 9 “國(guó)產(chǎn)GPU第一股”摩爾線(xiàn)程首季扭虧,但造血能力仍待考驗(yàn)
- 10 特斯拉宣布監(jiān)督版FSD登陸中國(guó)?
- 高級(jí)軟件工程師 廣東省/深圳市
- 自動(dòng)化高級(jí)工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷(xiāo)售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級(jí)銷(xiāo)售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專(zhuān)家 廣東省/江門(mén)市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市


分享





