MinGW编译动态库

简介: MinGW编译动态库

以之前的 universe 项目为例,提取码:mku9 。请下载后放到 C:\MinGW\projects 目录,如下:

现在用 MinGW 的 gcc 来编译出 libstar.a 静态库给 zeus 使用,如下:

cd C:\MinGW\bin
.\gcc.exe -c -o C:\MinGW\projects\universe\earth.o C:\MinGW\projects\universe\earth.c
.\gcc.exe -c -o C:\MinGW\projects\universe\sun.o C:\MinGW\projects\universe\sun.c
.\gcc.exe -c -o C:\MinGW\projects\universe\moon.o C:\MinGW\projects\universe\moon.c
.\gcc.exe -fPIC -shared -o C:\MinGW\projects\universe\libstar.so C:\MinGW\projects\universe\sun.o C:\MinGW\projects\universe\moon.o C:\MinGW\projects\universe\earth.o

上面这些命令,参数跟 在 《Linux环境编译动态库》是一样的。都是用 -shared 生成动态库。

然后执行以下命令来使用这个 libstar.so 动态库,如下:

.\gcc.exe -c -o C:\MinGW\projects\universe\zeus.o C:\MinGW\projects\universe\zeus.c
.\gcc.exe -o C:\MinGW\projects\universe\zeus2.exe C:\MinGW\projects\universe\zeus.o C:\MinGW\projects\universe\libstar.so

上图中,程序运行成功了,这个 exe 的依赖如下:



现在,我们有个以疑问,这个 libstar.so 到底是个什么东西?他的后缀名是 .so ,那他的文件格式就是 Linux 的 ELF 吗?

用 PEview 来查看这个 libstar.so 即可知道,如下:

上图中,这个文件开头是 MZ,所以他是一个 PE 格式的文件,.so 后缀只是挂羊头卖狗肉。

在 前文 《MSVC编译动态库》 编译Windows 原生动态库的时候,是有两个文件的,一个 lib (导入库),一个 dll (动态库)。

而 MinGW 生成的只有一个 libstar.so 文件,而 MinGW 也是偏 Windows 原生,那肯定是 lib 跟 dll 的东西都放在 libstar.so 里面了。

从 上图中的 dumpbin 依赖中也可以看出,libstar.so 实际上也是一个 dll。


libstar.so 这种集成的格式只是适合 gcc 链接器使用,而 MSVC 使用动态库需要 lib 跟 dll。有没一种办法,可以让 MinGW 编译出 lib(导入库) 跟 dll (动态库)呢?

.\gcc.exe -fPIC -shared -o C:\MinGW\projects\universe\star.dll C:\MinGW\projects\universe\sun.o C:\MinGW\projects\universe\moon.o C:\MinGW\projects\universe\earth.o -Wl,--out-implib,C:\MinGW\projects\universe\star.lib

上面我把 so 后缀改 dll 了,但是实际上没有区别。主要是后面的 -Wl,--out-implib 选项,这里生成了 lib 导入库。

上面的命令我没有指定 def 需要导出哪些函数,默认是全部都导出到 star.lib 。

现在的目录文件如下:


这样,MSVC 的 cl.exe 跟 link.exe 就能使用 gcc 生成的 star.lib 跟 star.dll 了。

由于上面 gcc 编译的默认是 32 位的,所以使用 x86 vs2019 的环境,不要用 64 的。

用 x86 Native Tools Command Prompt for VS 2019 打开一个新窗口,然后 进入 universe 目录,执行以下命令 :

cd C:\MinGW\projects\universe
cl.exe /c zeus.c
link.exe /OUT:zeus3.exe zeus.obj star.lib

正常运行,所以 gcc 编译出的动态库 ,是可以给 msvc 使用的。这是因为 这两个 编译器 处理 C语言程序 是 ABI 兼容的。但是 C++ 程序不是,gcc 跟 cl.exe 编译器编译 C++ 动态库,经常会遇到 ABI 兼容问题,具体下篇文章再讲。

目录
相关文章
|
5月前
|
存储 Cloud Native Linux
CMake学习之静态库动态库
CMake学习之静态库动态库
|
7月前
|
编译器 C++
使用64位的编译工具进行编译
本文记录了使用64位的编译工具进行编译的过程
|
8月前
|
编译器 C语言 Windows
Qt 使用MinGW编译器调用MinGW编译生成的dll
Qt 使用MinGW编译器调用MinGW编译生成的dll
122 0
|
10月前
|
安全 Linux 编译器
【Linux编译器gcc/g++】带你了解代码是如何变成可执行程序的!
【Linux编译器gcc/g++】带你了解代码是如何变成可执行程序的!
|
编译器 Linux vr&ar
MinGW编译静态库
MinGW编译静态库
305 0
|
Linux C++ Windows
MSVC编译动态库
MSVC编译动态库
166 0
|
XML 并行计算 Linux
MSVC编译静态库
MSVC编译静态库
256 0
|
Shell C语言 C++
MSYS2编译C/C++程序
MSYS2编译C/C++程序
625 0
|
Linux
MSVC编译多个C程序文件
MSVC编译多个C程序文件
118 0
|
编译器 C语言 C++
用msys2与msvc编译FFmpeg
本文讲解如何使用 msys2 + msvc 来编译 FFmpeg ,msys2 的安装请看 《MSYS2介绍》。
189 0