日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

C語(yǔ)言圖文并茂詳解鏈接過(guò)程_C 語(yǔ)言

作者:清風(fēng)自在?流水潺潺 ? 更新時(shí)間: 2022-06-18 編程語(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

欄目分類
最近更新