关于c:C进阶20链接过程简介

Summary

1)链接的定义:将指标文件最终链接为可执行程序

2)链接的2种形式:

  • 动态链接:指标文件会被间接*链接*进可执行程序slib.a被删掉后,程序仍旧能够运行
  • 动静链接:程序启动后才动静加载指标文件dlib.so被删掉后,程序无奈运行

3)动态链接和动静链接形式的抉择:

  • 动态链接:实用于比较简单的程序,开发进去不须要变动的,比方纯本地的记事本这种;把所有指标文件都编到可执行程序里,可能会导致可执行程序很大
  • 动静链接:一个大型软件的各个模块,如果采纳动静库的模式,哪个模块须要更新了,只须要批改这个模块,而后把dlib.so传到服务器上。用户在应用软件时,间接去服务器上拿这一个库更新下就能够了,而不须要更新整个程序。

链接过程简介

问题:工程里的每个.c源文件在编译后都会生成指标文件.o,那这些.o文件怎么生成最终的可执行程序.out呢?

答:链接器的次要作用是把各个模块间互相援用的局部解决好,使得各个模块之间能失常的连接。

1、动态链接

  • 链接器在链接时将库的内容间接退出到可执行程序中
  • 动态库的创立和应用
    1)生成动态库指标文件:gcc -c slib.c -o slib.o
    2)生成动态库:ar -q slib.a slib.o (输入:ar:creating slib.a;ar指的是archive,把前面列出的所有指标文件全都打包进slib.a中
    3)应用动态库编译:gcc 20-1.c slib.a -o 20-1.out (应用动态库进行编译)

2、动静链接

  • 可执行程序在运行时才动静加载库进行链接(运行时才去找我须要的symbol)
  • 库的内容不会进入到可执行程序中
// dlib.c
char* name()
{
    return "Dynamic Lib";
}

int add(int a, int b)
{
    return a+b;
}
// 20-2.c
#include <stdio.h>
#include <dlfcn.h>

int main()
{
    void* pdlib = dlopen("./dlib.so", RTLD_LAZY);    // pdlib指向了目录下dlib.so这个动静库
                                                     // 这个关上就相当于一个加载到内存里的指针
    
    char* (*pName)();        // 定义函数指针
    int (*pAdd)(int, int);
    
    if(NULL != pdlib)
    {
        pName = dlsym(pdlib, "name");    // 查找pdlib指向的动静库里的函数
        pAdd = dlsym(pdlib, "add");
        
        if(NULL != pName && NULL != pAdd)
        {
            printf("Name: %s\n", pName());
            printf("Ret: %d\n", pAdd(2, 3));
        }
        
        dlclose(pdlib);        // 敞开pdlib指向的动静库
    }
    else
    {
        printf("Cannot open dynamic lib...");
    }
}
// linux命令
gcc -shared dlib.c -o dlib.so : 创立了动静库dlib.so
gcc 20-2.c -ldl -o a.out : 应用动静库创立了可执行程序a.out
./a.out : 执行可执行程序

留神:-ldl通知编译器,这个程序用动静库的形式来编译,咱们的程序依赖动静库。如果动静库dlib.so删掉了,这个程序就运行不起来了,输入cannot open,因为a.out每次执行时须要去动静库里找symbol的(我要用啥,我每次得去你的仓库里拿),库都没了,天然找不到了。

本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请斧正。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理