網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一、鏈接器的意義
連接器的主要作用是把各個(gè)模塊之間相互引用的部分處理好,使得各個(gè)模塊之間能夠正確的銜接。
二、模塊鏈接
靜態(tài)鏈接
由鏈接器在鏈接時(shí)將庫(kù)的內(nèi)容直接加入到可執(zhí)行程序中
Linux下靜態(tài)庫(kù)的創(chuàng)建和使用
- 編譯靜態(tài)庫(kù)源碼:gcc -c lib.c -o lib.o
- 生成靜態(tài)庫(kù)文件:ar -q lib.a lib.o
- 使用靜態(tài)庫(kù)編譯:gcc main.c lib.a -o main.out
下面看一段靜態(tài)鏈接示例的代碼:
slib.c
char* name() { return "Static Lib"; } int add(int a, int b) { return a + b; }
Test.c
#include <stdio.h> extern char* name(); extern int add(int a, int b); int main() { printf("Name: %s\n", name()); printf("Result: %d\n", add(2, 3)); return 0; }
輸入gcc -c slib.c -o slib.o
,編譯靜態(tài)庫(kù)源碼:
輸入ar -q slib.a slib.o
,生成靜態(tài)庫(kù)文件:
輸入gcc Test.c slib.a -o Test.out
,使用靜態(tài)庫(kù)編譯,生成 .out 文件:
然后輸入 ./Test.out
,就可以運(yùn)行了,如下:
如果把 slib.o,slib.a 文件全部刪除,運(yùn)行 ./Test.out,發(fā)現(xiàn)能正常運(yùn)行,這就是前面說(shuō)的 .o 文件和 .a 文件完全被鏈接進(jìn)了可執(zhí)行程序里面,可執(zhí)行程序的運(yùn)行跟 .o 文件和 .a 文件沒(méi)有任何關(guān)系。
動(dòng)態(tài)鏈接
- 可執(zhí)行程序在運(yùn)行時(shí)才動(dòng)態(tài)加載庫(kù)進(jìn)行鏈接
- 庫(kù)的內(nèi)容不會(huì)進(jìn)入可執(zhí)行程序當(dāng)中
Linux下動(dòng)態(tài)庫(kù)的創(chuàng)建和使用
編譯動(dòng)態(tài)庫(kù)源碼:gcc -shared dlib.c -o dlib.so
使用動(dòng)態(tài)庫(kù)編譯:gcc main.c -ldl -o main.out
關(guān)鍵系統(tǒng)調(diào)用
- dlopen:打開(kāi)動(dòng)態(tài)庫(kù)文件
- dlsym:查找動(dòng)態(tài)庫(kù)中的函數(shù)并返回調(diào)用地址.
- dlclose:關(guān)閉動(dòng)態(tài)庫(kù)文件
下面看一個(gè)動(dòng)態(tài)鏈接示例:
dlib.c
char* name() { return "Dynamic Lib"; } int add(int a, int b) { return a + b; }
Demo.c
#include <stdio.h> #include <dlfcn.h> int main() { void* pdlib = dlopen("./dlib.so", RTLD_LAZY); char* (*pname)(); int (*padd)(int, int); if( pdlib != NULL ) { pname = dlsym(pdlib, "name"); padd = dlsym(pdlib, "add"); if( (pname != NULL) && (padd != NULL) ) { printf("Name: %s\n", pname()); printf("Result: %d\n", padd(2, 3)); } dlclose(pdlib); } else { printf("Cannot open lib ...\n"); } return 0; }
先輸入 gcc -shared dlib.c -o dlib.so
,編譯動(dòng)態(tài)庫(kù)源碼:
再輸入gcc Demo.c -ldl -o Demo.out
,使用動(dòng)態(tài)庫(kù)編譯,生成 .out 文件:
然后輸入 ./Demo.out
,就可以運(yùn)行了,如下:
如果把 dlib.so 給刪了,運(yùn)行就會(huì)報(bào)錯(cuò):
所以dlib.so 這個(gè)庫(kù)文件是在程序的運(yùn)行階段被動(dòng)態(tài)加載到內(nèi)存中去,這就是與靜態(tài)鏈接的區(qū)別。
三、小結(jié)
鏈接是指將目標(biāo)文件最終鏈接為可執(zhí)行程序
根據(jù)鏈接方式的不同,鏈接過(guò)程可以分為:
- 靜態(tài)鏈接:目標(biāo)文件直接鏈接進(jìn)入可執(zhí)行程序
- 動(dòng)態(tài)鏈接:在程序啟動(dòng)后才動(dòng)態(tài)加載目標(biāo)文件
原文鏈接:https://blog.csdn.net/weixin_43129713/article/details/123422920
相關(guān)推薦
- 2022-07-17 一起詳細(xì)聊聊C#中的Visitor模式_C#教程
- 2022-11-29 C#復(fù)制數(shù)組的兩種方式及效率比較_C#教程
- 2023-05-06 Go語(yǔ)言中Slice常見(jiàn)陷阱與避免方法詳解_Golang
- 2022-12-21 Python?threading中l(wèi)ock的使用詳解_python
- 2023-02-15 Python二進(jìn)制轉(zhuǎn)化為十進(jìn)制數(shù)學(xué)算法詳解_python
- 2023-01-01 echarts-xAxis-底部文字傾斜
- 2022-09-26 淺談Redis如何應(yīng)對(duì)并發(fā)訪問(wèn)_Redis
- 2022-09-18 C++?STL反向迭代器的實(shí)現(xiàn)_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支