午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

什么是動態(tài)鏈接與靜態(tài)鏈接?

 嵌入式大雜燴 2021-08-20

什么是鏈接?

對于初學C語言的朋友,可能對鏈接這個概念有點陌生,這里簡單介紹一下。

我們的C代碼編譯生成可執(zhí)行程序會經(jīng)過如下過程:

鏈接就是把目標文件與一些庫文件生成可執(zhí)行文件的一個過程。關于更詳細的編譯過程,可查閱往期筆記:【本質】你知道C語言編譯的過程嗎?

靜態(tài)、動態(tài)鏈接?

1、什么是靜態(tài)鏈接?

靜態(tài)鏈接是由鏈接器在鏈接時將庫的內(nèi)容加入到可執(zhí)行程序中的做法。

鏈接器是一個獨立程序,將一個或多個庫或目標文件(先前由編譯器或匯編器生成)鏈接到一塊生成可執(zhí)行程序。

這里的庫指的是靜態(tài)鏈接庫,Windows下以.lib為后綴,Linux下以.a為后綴。

2、什么是動態(tài)鏈接?

動態(tài)鏈接(Dynamic Linking),把鏈接這個過程推遲到了運行時再進行,在可執(zhí)行文件裝載時或運行時,由操作系統(tǒng)的裝載程序加載庫。

這里的庫指的是動態(tài)鏈接庫,Windows下以.dll為后綴,Linux下以.so為后綴。

值得一提的是,在Windows下的動態(tài)鏈接也可以用到.lib為后綴的文件,但這里的.lib文件叫做導入庫,是由.dll文件生成的。

3、靜態(tài)鏈接與動態(tài)鏈接的優(yōu)缺點?

(1)靜態(tài)鏈接的優(yōu)缺點:

優(yōu)點:

  • 代碼裝載速度快,執(zhí)行速度略比動態(tài)鏈接庫快;
  • 只需保證在開發(fā)者的計算機中有正確的.lib文件,在以二進制形式發(fā)布程序時不需考慮在用戶的計算機上.lib文件是否存在及版本問題。

缺點:

  • 使用靜態(tài)鏈接生成的可執(zhí)行文件體積較大,包含相同的公共代碼,造成浪費。

(2)動態(tài)鏈接的優(yōu)缺點:

優(yōu)點:

  • 生成的可執(zhí)行文件較靜態(tài)鏈接生成的可執(zhí)行文件??;
  • 適用于大規(guī)模的軟件開發(fā),使開發(fā)過程獨立、耦合度小,便于不同開發(fā)者和開發(fā)組織之間進行開發(fā)和測試;
  • 不同編程語言編寫的程序只要按照函數(shù)調(diào)用約定就可以調(diào)用同一個DLL函數(shù);
  • DLL文件與EXE文件獨立,只要輸出接口不變(即名稱、參數(shù)、返回值類型和調(diào)用約定不變),更換DLL文件不會對EXE文件造成任何影響,因而極大地提高了可維護性和可擴展性;

缺點:

  • 使用動態(tài)鏈接庫的應用程序不是自完備的,它依賴的DLL模塊也要存在,如果使用載入時動態(tài)鏈接,程序啟動時發(fā)現(xiàn)DLL不存在,系統(tǒng)將終止程序并給出錯誤信息;
  • 速度比靜態(tài)鏈接慢;

靜態(tài)、動態(tài)鏈接實驗

下面的實驗基于Windows平臺。Windows下的靜態(tài)鏈接、動態(tài)鏈接實驗網(wǎng)上較多的是使用一些IDE如Visual Studio等通過圖形界面來操作,這樣就會掩蓋了很多細節(jié)。

本篇筆記我們不使用IDE,而是以Windows平臺搭配MinGW來演示,以便于日后我們在Linux下操作時可以比較快地進行切換。

我們先編寫如下代碼(共三個文件):

文件1(main.c):

#include "test.h"

int main(void)
{
print_hello();
system("pause");
return 0;
}

文件2(test.c):

#include "test.h"

void print_hello(void)
{
printf("hello world\n");
}

文件3(test.h):

#ifndef __TEST_H
#define __TEST_H

#include <stdio.h>
#include <stdlib.h>

void print_hello(void);

#endif

此時我們的代碼目錄如下:

1、靜態(tài)鏈接實驗

進入我們的代碼路徑,輸入命令:

gcc -c test.c main.c

編譯、匯編指定的源文件(也就是編譯源文件),將每一個源文件編譯成對應的目標文件。此時文件夾下多出了test.omain.o文件:

接下來使用ar工具把test.omain.o打包成一個靜態(tài)庫文件lib_test.lib,輸入命令:

ar rv lib_test.lib test.o main.o

其實,用MinGW可以生成.a后綴和.lib后綴的靜態(tài)鏈接庫,這里生成的是.lib后綴的靜態(tài)庫。此時文件夾下多出了.lib文件:

然后把這個靜態(tài)庫鏈接成可執(zhí)行文件lib_test.exe,輸入命令:

此時文件夾下多出了可執(zhí)行文件lib_test.exe

雙擊運行:

可見,運行結果與預期一致,說明我們使用靜態(tài)鏈接的方式生成的可執(zhí)行文件沒問題。

這個可執(zhí)行文件的運行并不依賴于lib_test.lib文件,我們可以試著把這個文件刪除之后再運行,仍然可以正常運行。

2、動態(tài)鏈接實驗

我們把test.c編譯成動態(tài)庫文件dll_test.dll,輸入命令:

gcc test.c -shared -o dll_test.dll

此時文件夾下多出了動態(tài)庫文件dll_test.dll

我們用該動態(tài)庫文件dll_test.dllmain.c一起編譯生成可執(zhí)行文件dll_test.exe,輸入命令:

gcc dll_test.dll main.c -o dll_test.exe

此時文件夾下多出了可執(zhí)行文件dll_test.exe

雙擊運行:

可見,運行結果與預期一致,說明我們使用動態(tài)鏈接的方式生成的可執(zhí)行文件沒問題。

這個可執(zhí)行文件的運行依賴于dll_test.dll文件,我們可以試著把這個文件刪除之后再運行。運行出現(xiàn)如下錯誤:

那是因為使用動態(tài)鏈接庫的應用程序不是自完備的,它依賴的DLL模塊也要存在。

動態(tài)鏈接的方式使用得很廣泛,比如我們電腦系統(tǒng)盤的System32文件夾下就有很多動態(tài)鏈接庫文件:

騰訊QQ安裝目錄下:

上面使用的命令其實與Linux下操作的命令大多都很相似,我們只要明白這么一回事就可以很快地在Linux下進行操作。

    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多