msys2-gcc动态库使用 - 弦外之音

/ 0评 / 0

上篇文章是《msys2-gcc静态库使用》,本文来讲动态库,代码如下:

myTest.h :

int my_test(int a, int b);

myTest.c :

#include "myTest.h"
int my_test(int a, int b) {
    return a + b;
}

myMath.h :

int add(int a, int b);

myMath.c:

#include "myMath.h"
#include "myTest.h"
int add(int a, int b) {
    return my_test(a,b);
}

main.c :

#include <stdio.h>
#include "myMath.h"
int main()
{
    int a = 3, b = 5;
    printf("a+b=%d\n", add(3, 5));
    return 0;
}

代码已经写好,先执行一下命令编译出 .o 后缀的文件。

gcc -c myMath.c -o myMath.o
gcc -c myTest.c -o myTest.o
gcc -c main.c -o main.o

msys2 环境操作下,gcc 生成的动态库是 xxx.dll 的,不是xxx.so。

要编译 mymath.dll 动态库 ,常规的做法是 gcc -c -fPIC myMath.c -o myMath.o ,把 C 代码编译成 object 文件,然后用 gcc -shared myMath.o -o mymath.dll -Wl,--out-implib,mymath.lib 把 object 文件转成 .dll 动态库文件。但我们现在有一个嵌套库 myTest ,而且不想暴露给别人,这时候应该如何编译。

其实跟静态库的编译差不多,把 myTest.o 文件加进去就行,gcc -shared myMath.o myTest.o -o mymath.dll -Wl,--out-implib,mymath.lib。我们可以用以下两个不同的命令看一下生成的 mymath.dll 有什么区别。

第一个命令:gcc -shared myMath.o -o mymath_1.dll -Wl,--out-implib,mymath_1.lib

第二个命令:gcc -shared myMath.o myTest.o -o mymath_2.dll -Wl,--out-implib,mymath_2.lib

第一个命令是没加 myTest.o 的。

第一个命令直接报错了,那就不管跳过,咱们来看看 mymath_2.dll 跟 myMath.o myTest.o 的内容有没相同的地方。如下图:

可以看到 .so 文件,其实也是拥有 myTest.o 跟 myMath.o 里面的部分内容。所以无论是静态库还是动态库,他们都是把一堆 .o 文件合在一个文件里面,只不过动态库 .so 加了一个附加信息来实现动态加载,静态库加了一些附加信息来实现静态加载。

此时, myTest.o 跟 myMath.o 已经没用了,可以删除,只需要把 mymath_2.dll 给别人用就行,可以执行以下命令生成 main 可执行文件。

#第一种方式
gcc main.o mymath_2.dll -o main.exe
#第二种方式
gcc main.o -o main -lmymath_2 -L.

相关阅读:

  1. 《MinGW gcc 生成动态链接库 dll 的一些问题汇总》

由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。

发表回复

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