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 兼容问题,具体下篇文章再讲。

目录
相关文章
|
设计模式 JavaScript 前端开发
深入了解Vue.js框架:构建现代化的用户界面
深入了解Vue.js框架:构建现代化的用户界面
1152 0
|
jenkins Java 应用服务中间件
idea一键部署远程项目
idea一键部署远程项目
|
Linux 编译器 数据库
pacman包管理器介绍
pacman包管理器介绍
1109 0
|
算法 C语言
使用指针来优化C语言程序性能
在C语言中,指针是一种强大且重要的概念。合理地使用指针可以提高程序的性能,减少内存的开销,并使代码更加简洁和易于维护。本文将介绍一些使用指针来优化C语言程序性能的技术。
563 0
|
监控
idea插件报错导致不能启动的处理技巧
在安装IDEA的插件时,难免会遇到插件不合理导致的IDEA启动时报错,没有办法从IDEA的plugins管理面板卸载插件,那怎么办呢? 答:手动删除。查找IDEA的日志C:\Users\{username}\.IntelliJIdea2016.1\system\log\idea.log,启动IDEA并监控该日志行为及报错信息;然后在电脑上安装Everything (该工具可
6787 1
|
NoSQL 调度 数据中心
|
人工智能 Java 程序员
一文彻底搞清楚C语言的条件语句的Switch语句
本文详细介绍了C语言中的switch语句,包括其语法格式、运行流程、示例代码及注意事项。switch语句不仅使多分支选择更加清晰易读,还能在某些情况下提升性能。通过具体实例,如判断月份天数和数字转星期,帮助读者更好地理解和应用这一控制结构。
1249 1
一文彻底搞清楚C语言的条件语句的Switch语句
|
区块链
C 标准库 - <locale.h>详解
`&lt;locale.h&gt;` 是 C 标准库中的头文件,用于处理地域设置(locale),影响程序的行为,如数字、货币和日期格式化。重要类型包括 `locale_t`;宏有 `LC_ALL`、`LC_COLLATE` 等;主要函数包括 `setlocale`、`newlocale`、`frelocale`、`duplocale`、`strcoll` 和 `mblen`。
615 12
|
XML JSON JavaScript
推荐一个比较好用的c++版本http协议库-cpp-httplib
推荐一个比较好用的c++版本http协议库-cpp-httplib
2085 1
|
JavaScript Java API
深入了解后端开发:从基础到进阶
【10月更文挑战第6天】深入了解后端开发:从基础到进阶