首頁 > 軟體

C語言圖文並茂詳解連結過程

2022-04-19 13:00:16

一、連結器的意義

聯結器的主要作用是把各個模組之間相互參照的部分處理好,使得各個模組之間能夠正確的銜接。

二、模組連結

靜態連結

由連結器在連結時將庫的內容直接加入到可執行程式中

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: %sn", name());
 
    printf("Result: %dn", 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: %sn", pname());
            printf("Result: %dn", 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 這個庫檔案是在程式的執行階段被動態載入到記憶體中去,這就是與靜態連結的區別。

三、小結

連結是指將目標檔案最終連結為可執行程式

根據連結方式的不同,連結過程可以分為:

  • 靜態連結:目標檔案直接連結進入可執行程式
  • 動態連結:在程式啟動後才動態載入目標檔案

到此這篇關於C語言圖文並茂詳解連結過程的文章就介紹到這了,更多相關C語言 連結過程內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com