关于Dll工程转静态库lib工程遇到的坑

DLL转静态库实践

最近在编译github上的开源项目,下载下来后,查看源码是dll工程且类是导出类,使用到导出string标准库中的字符串问题,由于接口中涉及到string类,就涉及到谁开辟谁释放的跨组件问题,加入工程后,如果主进程(调用进程为多线程MT形式)就会出现编译错误或模块内存释放问题,在这里要理解的知识点是:

(1)组件和调用进程同为MD(或MDd)多线程模式,则组件与调用进程使用的是主进程的内存空间,不存在跨模块释放内存问题;

(2)组件和调用进程同为MT(或MTd)多线程模式,则组件与调用进程使用的是各自模块的内存空间,给子有相应的内存分配器,除非使用统一的CoAlloc或其他API使得组件和主进程使用同一内存空间,这样就不存在内存组件开辟然后主进程释放,或主进程开辟内存空间但是dll释放导致跨模块释放崩溃问题;

解决以上跨模块问题的方法有两种:

(1)保证主进程与Dll组件同时为MD或MDd多线程模式,这样两个组件不存在跨进程内存分配问题(都为进程内存)

(2)把Dll工程更改为static库工程,使得静态库的多线程模式和主进程一致,编译后的lib直接添加到主进程调用;

 

方法(1)虽然可以解决问题,按照我的习惯:

(1)一个项目能不依赖其他dll的就不依赖其他dll,尽量减少dll的依赖,所以提倡使用静态库链接。

因为dll多了,可能出现A和B都依赖C,而C存在多个接口都不一样的版本,这就尴尬了,需要分文件存放不同版本dll,项目很难运维;增加打包繁杂度,特别是项目打了,依赖的组件上百个,容易漏掉;一致性不太好,比如win7上可用的dll在win server r2上不能用(很正常涉及到音视频,服务器机器上无对应组件)。等等原因;

(2)组件少,可移植性强,

所以,我们可以考虑将dll工程转为静态库工程,然后将静态库工程添加到调用进程,这样会解决若干麻烦,接下来告诉你如何将已有的dll工程转为静态库工程(当然,最简单的办法就是新建静态库,然后添加所有文件。但是如果代码量大,文件多就非常麻烦!),具体步骤如下

(1)将项目-->属性-->常规-->配置类型(父项:项目默认值)更改为静态库lib

(2)将项目-->属性-->常规-->目标文件扩展名(父项:常规)更改为.lib

(3)重点在这里:将dll类或函数的导出声明去掉,随意找到一个类,跳转到导出宏定义声明,这里找到的定义在

     \src\SimpleAmqpClient\Util.h

(4)更改宏定义为:

        

(4)更改宏定义为:
        #ifdef WIN32
        #ifdef SimpleAmqpClient_EXPORTS
        #define SIMPLEAMQPCLIENT_EXPORT /*__declspec(dllexport)*/
        #else
        #define SIMPLEAMQPCLIENT_EXPORT /*__declspec(dllimport)*/
        #endif
        #else
        #define SIMPLEAMQPCLIENT_EXPORT
        #endif

 这里仅仅是举例,具体宏定义见自己工程的dll导出声明宏,去掉dllexport和dllimport声明即可。

(5)最后编译生成静态库即可,否则报错提示dllimport,改单词仅仅适用于dll,也就是存在改单词会让vs误以为是动态库导入

 

快来成为我的朋友或合作伙伴,一起交流,一起进步!
QQ群:961179337
微信:lixiang6153
邮箱:lixx2048@163.com
公众号:IT技术快餐
更多资料等你来拿!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝壳里的沙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值