binutils——如何将程序打包为库文件

在我们开发项目过程中。经常会遇到使用第三方程序的情况。而这个时候我们只需要调用第三方提供的库文件和接口文档就可以了,我们并看不到源代码。而这个库文件又是许多源文件编译得来的。

问题:我们如何将多个源文件打包成一个库文件呢?

静态库文件

  • 由链接器在链接时将库的内容直接加入到可执行程序中。
  • Linux下静态库的创建和使用
    1. 编译静态库源码:gcc –c lib.c –o lib.o
    2. 生成静态库文件: ar –q lib.a lib.o
    3. 使用静态库编译: gcc main.c lib.a –o main.out

操作过程:

delphi@delphi-vm:~/workspace$ gcc -c dlib.c -o slib.o <--1
delphi@delphi-vm:~/workspace$ ls
slib.c  slib.o  main.c
delphi@delphi-vm:~/workspace$ ar -q dlib.a slib.o <--2
ar: creating slib.a
delphi@delphi-vm:~/workspace$ ls
slib.a  slib.c  slib.o  main.c
delphi@delphi-vm:~/workspace$ gcc main.c slib.a -o main.out <--3
delphi@delphi-vm:~/workspace$ ls
slib.a  slib.c  slib.o  main.c  main.out
delphi@delphi-vm:~/workspace$ rm slib.c slib.o
delphi@delphi-vm:~/workspace$ rm slib.a main.c
delphi@delphi-vm:~/workspace$ ls
main.out
delphi@delphi-vm:~/workspace$ ./main.out 
Name: Static Lib
Result: 5

我们知道:
当可执行程序需要与静态库进行链接时,所使用到的库中的函数和数据会被拷贝到最终的可执行文件中。(并不是库文件全部装入到可执行文件,而是用到哪些函数就装入哪些函数)。

问题:那么多个可执行程序都需要用到同一个静态库文件,岂不是每个可执行文件都存在库文件的拷贝?

动态库文件

  • 可执行程序在运行时才动态加载库进行链接
  • 库的内容不会进入可执行程序当中
  • Linux下动态库的创建和使用
    1. 编译动态库源码:gcc –shared dlib.c –o dlib.so
    2. 使用动态库编译:gcc main.c –ldl –o main.out
    3. 关键系统调用
      a) dlopen:打开动态库文件
      b) dlsym:查找动态库中的函数并返回调用地址
      c) dlclose:关闭动态库文件

示例代码:动态库链接示例

#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;
}

操作过程:
delphi@delphi-vm:~/workspace$ gcc -shared dlib.c -o dlib.so
delphi@delphi-vm:~/workspace\$ gcc main.c -ldl -o test.out
delphi@delphi-vm:~/workspace\$ rm dlib.c dlib.so main.c
delphi@delphi-vm:~/workspace\$ ls
main.out test.out
delphi@delphi-vm:~/workspace\$ ./test.out
Cannot open lib …
delphi@delphi-vm:~/workspace\$ gcc -shared dlib.c -o dlib.so
delphi@delphi-vm:~/workspace\$ ./test.out
Name: Dynamic Lib
Result: 5

静态库与动态库的区别

  • 静态库:目标文件直接链接进入可执行程序
  • 动态库:在程序启动后才动态加载目标文件

也就是说,通过静态链接的目标文件,在运行时可以不需要静态库文件的存在;而通过动态链接的目标文件,则需要动态库文件的存在才可以运行,否则则提示:Cannot open lib。。。。

  • 动态链接可执行文件比功能相同的静态链接可执行文件体积小。它能够节省磁盘空间和虚拟内存,因为函数库只有在需要时才被映射到进程中。
  • 所有动态链接到某个特定库函数的可执行文件在运行时共享该函数库的一个单独拷贝。

这里写图片描述

猜你喜欢

转载自blog.csdn.net/small_prince_/article/details/80670305
今日推荐