如何在在動態(tài)鏈接庫中調(diào)用外部函數(shù)?
大家好,我是一個動態(tài)鏈接庫!
這個名字,相信你一定早就如雷貫耳了。
在計算機早期時代,由于內(nèi)存資源緊張,我可是發(fā)揮了重大的作用!
不論是在 Windows 系統(tǒng)中,還是在 Unix 系列平臺上,到處都能見到我的身影,因為我能為大家節(jié)省很多資源啊,資源就是人民幣!
愉快的玩耍
比如:我的主人編寫了這么一段簡單的代碼:
# 文件:lib.c
#include <stdio.h>
int func_in_lib(int k)
{
printf("func_in_lib is called ");
return k + 1;
}
只要用如下命令來編譯,我就誕生出來了 lib.so,也就是一個動態(tài)鏈接庫:
$ gcc -m32 -fPIC --shared -o lib.so lib.c
這個時候,主人隨便把我丟給誰,我都可以為他服務(wù),只要他調(diào)用我肚子里的這個函數(shù) func_in_lib 就可以了。
雖然目前你看到我提供的這個函數(shù)很簡單,但是道理都是一樣的,后面如果有機會,我就在這個函數(shù)里來計算機器人的運動軌跡,給你瞧一瞧!
例如:張三今天寫了一段代碼,需要調(diào)用我的這個函數(shù)。
張三這個人比較喜歡騷操作,明明他在編譯可執(zhí)行程序的時候,把我動態(tài)鏈接一下就可以了,就像下面這樣:
$ gcc -m32 -o main main.c ./lib.so
但是張三偏偏不這么做,為了炫技,他選擇使用 dlopen 動態(tài)加載的方式,來把我從硬盤上加載到進程中。
咱們來一起圍觀一下張三寫的可執(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;
// 打開動態(tài)庫
void *handle = dlopen("./lib.so", RTLD_NOW);
if (handle)
{
// 查找動態(tài)庫中的函數(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ù)先知道我肚子里的這個函數(shù)名稱是 func_in_lib,所以他使用了系統(tǒng)函數(shù) dlsym(handle, "func_in_lib"); 來找到這個函數(shù)在內(nèi)存中的加載地址,然后就可以直接調(diào)用這個函數(shù)了。
張三編譯得到可執(zhí)行文件 main 之后,執(zhí)行結(jié)果完全正確,很開心!
悲從中來
可是有一天,我遇到一件煩人的事情,我的主人說:你這個服務(wù)函數(shù)的計算過程太單調(diào)了,給你找點樂子,你在執(zhí)行的時候啊,到其他一個外部模塊里調(diào)用一個函數(shù)。
話剛說完,就丟給我一個函數(shù)名:void func_in_main(void);。
也就是說,我需要在我的服務(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;
}
那么這個函數(shù)在哪里呢?天哪,我怎么知道這個函數(shù)是什么鬼?怎么才能找到它藏在內(nèi)存的那個角落(地址)里?
不管怎么樣,主人修改了代碼之后,還是很順利的把我編譯了出來:
$ gcc -m32 -fPIC --shared -o lib.so lib.c
編譯指令完全沒有變化。
因為我僅僅是一個動態(tài)鏈接庫,這個時候即使我不知道 func_in_main 函數(shù)的地址,也是可以編譯成功的。
只不過我要把這個家伙標(biāo)記一下:誰要是想使用我,就必須告訴我這個家伙的地址在哪里!,否則就別怪我耍賴。

請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
-
7月8日立即報名>> 【在線會議】英飛凌新一代智能照明方案賦能綠色建筑與工業(yè)互聯(lián)
-
7月22-29日立即報名>> 【線下論壇】第三屆安富利汽車生態(tài)圈峰會
-
7.30-8.1火熱報名中>> 全數(shù)會2025(第六屆)機器人及智能工廠展
-
7月31日免費預(yù)約>> OFweek 2025具身智能機器人產(chǎn)業(yè)技術(shù)創(chuàng)新應(yīng)用論壇
-
免費參會立即報名>> 7月30日- 8月1日 2025全數(shù)會工業(yè)芯片與傳感儀表展
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍(lán)皮書》
推薦專題