網站首頁 編程語言 正文
一、鏈接器的意義
連接器的主要作用是把各個模塊之間相互引用的部分處理好,使得各個模塊之間能夠正確的銜接。
二、模塊鏈接
靜態鏈接
由鏈接器在鏈接時將庫的內容直接加入到可執行程序中
Linux下靜態庫的創建和使用
- 編譯靜態庫源碼:gcc -c lib.c -o lib.o
- 生成靜態庫文件:ar -q lib.a lib.o
- 使用靜態庫編譯:gcc main.c lib.a -o main.out
下面看一段靜態鏈接示例的代碼:
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
,編譯靜態庫源碼:
輸入ar -q slib.a slib.o
,生成靜態庫文件:
輸入gcc Test.c slib.a -o Test.out
,使用靜態庫編譯,生成 .out 文件:
然后輸入 ./Test.out
,就可以運行了,如下:
如果把 slib.o,slib.a 文件全部刪除,運行 ./Test.out,發現能正常運行,這就是前面說的 .o 文件和 .a 文件完全被鏈接進了可執行程序里面,可執行程序的運行跟 .o 文件和 .a 文件沒有任何關系。
動態鏈接
- 可執行程序在運行時才動態加載庫進行鏈接
- 庫的內容不會進入可執行程序當中
Linux下動態庫的創建和使用
編譯動態庫源碼:gcc -shared dlib.c -o dlib.so
使用動態庫編譯:gcc main.c -ldl -o main.out
關鍵系統調用
- dlopen:打開動態庫文件
- dlsym:查找動態庫中的函數并返回調用地址.
- dlclose:關閉動態庫文件
下面看一個動態鏈接示例:
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
,編譯動態庫源碼:
再輸入gcc Demo.c -ldl -o Demo.out
,使用動態庫編譯,生成 .out 文件:
然后輸入 ./Demo.out
,就可以運行了,如下:
如果把 dlib.so 給刪了,運行就會報錯:
所以dlib.so 這個庫文件是在程序的運行階段被動態加載到內存中去,這就是與靜態鏈接的區別。
三、小結
鏈接是指將目標文件最終鏈接為可執行程序
根據鏈接方式的不同,鏈接過程可以分為:
- 靜態鏈接:目標文件直接鏈接進入可執行程序
- 動態鏈接:在程序啟動后才動態加載目標文件
原文鏈接:https://blog.csdn.net/weixin_43129713/article/details/123422920
相關推薦
- 2022-04-06 Android關于Button背景或樣式失效問題解決方法_Android
- 2022-08-20 React的生命周期詳解_React
- 2022-02-15 使用數組的sort方法完成項目中的排序功能(數組sort方法與chart圖表展示結合)
- 2022-05-12 tp5使用阿里云oss存儲圖片
- 2022-11-10 Android傳感器的簡單使用方法_Android
- 2022-03-09 C++使用map實現多進程拷貝文件的程序思路_C 語言
- 2023-07-10 分布式緩存之Redis(持久化、主從、哨兵、分片集群)
- 2022-07-03 C#并行編程之信號量_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支