MinGW、Linux GNU、MSVC编译和链接动态库的分析
这几天研究CMake跨平台项目嘛,用了以下几种编译器:
VS2019(MSVC)
Linux GNU
MinGW
编译之后发现链接动态库发现以下问题:
- VS2019中如果直接链接CMakeLists.txt中生成的动态库,编译的时候会发生unreferenced的错误,相同的CMake项目使用MinGW或者Linux GNU进行编译的话则没有问题。
对于这个问题,我回想起了在上一家公司实习的时候,写VS项目的dll要配置导出接口的事情,当时之所以觉得导出接口陌生是因为我在实习前基本上都是用MinGW,所以编译产生的动态库不需要导出接口就可以直接用,当时没有细究这个问题,以为在windows下都是一样的,然后现在就遇到了这个问题。
通过对不同平台以及不同编译器进行测试,我得到了以下结论:
- 结论一:MinGW和Linux GNU都是GNU,所以它们编译产生的文件有相似的地方:静态库的后缀名都是.a,但是区别也有,Linux GNU编译动态库产生so,MinGW编译动态库会产生dll(如果使用MSYS2的话确实是编译出so),不过这不重要;
- 结论二:MinGW编译动态库除了产生dll外还会产生一个dll.a;
- 结论三:VS项目的函数如果使用函数导出接口修饰的话,编译动态库也会产生一个与dll同名的lib。
然后编写lua的C包的时候也发现了:
lua在require或者loadlib一个C模块的时候,如果模块是用VS编译产生的话,函数必须具有导出接口,而如果模块是用MinGW编译产生的话,则不需要,也就是说MinGW编译生成动态库时,动态库中的函数默认具有导出接口,这部分我应该开一篇新文,在这里只是题外话。
然后再进行测试,我发现MinGW编译动态库产生的dll可以直接进行动态库链接,结论2中产生的dll.a这个引导库也许是为了和在Windows下使用动态库一致,但是由于MinGW生成动态库时一定会生成dll.a所以我没办法判断MinGW链接动态库的时候是链接dll还是链接dll.a,反正在lua的例子中可以知道MinGW生成的动态库中所有函数都是具有导出接口的;而VS编译动态库产生的dll必须需要有一个引导库文件来帮助完成链接工作。
在cmake中进行动态库链接的话:
target_link_libraries(main testlib_shared)
#这一行代码在MinGW、Linux GNU上cmake产生的makefile是可以通过编译的,而如果testlib_shared中用到的函数有使用函数导出接口修饰的话,cmake产生的VS项目也可以通过编译
当然最后得有一个结论:为了让cmake项目能够跨平台,链接的动态库中使用到的函数应该使用函数导出接口修饰或者直接链接静态库,这样项目才能够在VS上通过编译,而代码中添加函数导出接口修饰的话需要用宏_WIN32去判断是不是VS项目:
#ifndef _WIN32 //如果没有_WIN32的宏,说明不是MSVC项目,自然就不用导出接口
#define TEST_DLL_API
#endif
#ifndef TEST_DLL_API
#define TEST_DLL_API __declspec(dllexport)
#endif
#include <stdio.h>
TEST_DLL_API int hello();
MinGW、Linux GNU、MSVC编译和链接动态库的分析的更多相关文章
- Linux程序编译链接动态库版本号的问题
不同版本号的动态库可能会不兼容,假设程序在编译时指定动态库是某个低版本号.执行是用的一个高版本号,可能会导致无法执行. Linux上对动态库的命名採用libxxx.so.a.b.c的格式.当中a代表大 ...
- Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别
昨天在自己的CentOs7.1上写makefile的时候,发现在一个C程序在编译并链接一个已生成好的lib动态库的时候出错.链接命令大概是这样的: [root@typecodes tcpmsg]# g ...
- Makefile 编译动态库文件及链接动态库
本文为原创文章,转载请指明该文链接 文件目录结构如下 dynamiclibapp.c Makefile comm/inc/apue.h comm/errorhandle.c dynamiclib/Ma ...
- 在Linux使用GCC编译C语言共享库
在Linux使用GCC编译C语言共享库 对任何程序员来说库都是必不可少的.所谓的库是指已经编译好的供你使用的代码.它们常常提供一些通用功能,例如链表和二叉树可以用来保存任何数据,或者是一个特定的功能例 ...
- gcc编译工具生成动态库和静态库之一----介绍
1.库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. ...
- C++---初识《通过g++ / makefile 编译和调用动态库so文件》(ubuntu)
C++---初识<通过g++ / makefile 编译和调用动态库so文件>(ubuntu) ------------------------目录------------------- ...
- gcc编译工具生成动态库和静态库
一. 库的分类 1.1. 静态库(.a) 1.1.1. 静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大.所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 1. ...
- 修改OpenSSL默认编译出的动态库文件名称
在 Windows 平台上调用动态链接库 dll 文件时,有两种方式:a) 隐式的加载时链接:使用 *.lib (导入库)文件,在 IDE 的链接器相关设置中加入导入库 lib 文件的名称,或在程序中 ...
- linux c编程调用系统的动态库时,要使用dlopen等函数吗?
同问 linux c编程调用系统的动态库时,要使用dlopen等函数吗? 2012-11-27 21:55 提问者: hnwlxyzhl 我来帮他解答 满意回答 2012-12-07 09:08 li ...
- 关于Linux静态库和动态库的分析
关于Linux静态库和动态库的分析 关于Linux静态库和动态库的分析 1.什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可运行代码的二进制形式.能够被操作系统加 ...
随机推荐
- 用ChatGPT,绘制一个账号系统的C4架构图
hi,我是熵减,见字如面. 昨天我们用ChatGPT来设计一个账号系统,并尝试输出:模型表,类关系图,序列图,状态图等常用的架构设计中常用的元素. 今天,我们继续向更高层级延伸一下,看ChatGPT能 ...
- WPF BasedOn 自定义样式 例:ComboBox 组合框
自定义样式 ComboBox 组合框 <Window.Resources> <Style x:Key="ComboBox01" TargetType=" ...
- GPIO 和中断控制 LED 的状态
中断的概念 中断是 MCU 强行从正常的主任务切换到由某些内部或外部条件的紧急任务.中断的优先程度远远高于主任务,MCU 会暂时把主任务挂起,转而处理中断任务,之后再执行主任务. 引起中断的外部条件来 ...
- KingbaseES R6集群物理copy方式手工添加新备库节点
案例说明:对于主库数据量比较大的环境,在添加新节点是可以采用在线clone方式创建新的备库节点,也可以在离线的状态下,直接拷贝其中一个备库的所有集群相关目录来创建新的备库节点.本案例介绍了通过离线物理 ...
- 剖析flutter_download_manager学习如何做下载管理,暂停和取消
前言 内容类应用中图片或文件下载,一般应用中应用更新和升级,这些都是经典的下载场景.下载是项目中基础且重要的模块. 从代码逻辑复用性和人力成本考虑,一直想实现一个纯Dart实现的下载库,作为技术储备. ...
- Oracle 11g 单机服务器ASM部署
Oracle oracle,相比都有所了解,是一家企业级的数据库公司(收费),上图是oracle官网,也是对外的服务平台 oracle有自己独特的安装方式:ASM : 自动存储管理(ASM,Au ...
- Anaconda 环境中安装OpenCV (cv2)
1.使用Anaconda 的对应环境,查看环境中的Python版本号 (1)使用Anaconda 查看存在的环境:conda info --env (2)激活环境:conda activate XXX ...
- VUE环境运行搭建
第一步:下载安装node.js 1.下载node.js,vue的运行是要依赖于node的npm的管理工具来实现,所以第一步我们需要安装 Node.js,访问官网 https://nodejs.org/ ...
- .NET CORE 控制台程序在CentOS 7 后台运行指令
1.后台运行服务 >/dev/null & 不输出任何信息 & 记录控制台所有信息 记录错误信息 :/dev/null 2>log & 指令:nohup XXX.d ...
- java正则解析ip
public class test { public static void main(String[] args) { // TODO Auto-generated method stub Stri ...