浅墨浓香

想要天亮进城,就得天黑赶路。

导航

第20课 链接过程简介

Posted on 2016-03-27 13:36  浅墨浓香  阅读(735)  评论(5编辑  收藏  举报

1. 链接器的意义

(1)每个C语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件。

(2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接。

 

2. 静态链接

(1)由链接器在链接时将库的内容直接加入到可执行程序中

 

(2)Linux下静态链的创建和使用

①编译静态库源码:gcc –c  lib.c –o lib.o

②生成静态库文件:ar –q lib.a lib.o //将lib.o与其他文件打包到lib.a中

③使用静态库编译:gcc main.c lib.a –o main.out

【编程实例】静态链接示例

 //slib.c库文件

char* name()
{
    return "Static Lib";
}


int add(int a, int b)
{
    return a + b;
}

//20-1.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;
}

3. 动态链接

(1)可执行程序在运行时才动态加载库进行链接

 

(2)库的内容不会进入可执行程序当中

(3)Linux下动态库的创建和使用

  ①编译动态库源码:gcc –shared  dlib.c –o dlib.so

  ②使用动态库编译:gcc main.c -ldl –o main.out

(4)动态库的使用(关键的API调用)

  ①打开动态库:dlopen

  ②查找动态库中的函数并返回调用地址:dlsym

  ③关闭动态库:dlclose

【编程实验】动态链接示例

 //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);

    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;

}

4. 小结

(1)链接是指将目标文件最终链接为可执行程序

(2)根据链接方式的不同,链接过程可以分为:

  ①静态链接:目标文件直接链接进入可执行程序

  ②动态链接:在程序启动后才动态加载目标文件