Qt与vs编写的dll通讯遇中的坑

14 篇文章 3 订阅

一、前言:

因为实际开发过程中遇到Qt调用vs编写的sdk,故用vs封装成纯C++的dll提供Qt使用,因为懒得迁移整个工程到Qt环境,毕竟没学过Qt,光是搭建环境,怎么使用creator就很多时间折腾了,时间成本很高。

二、新建vs的dll

1、生成dll、lib
在这里插入图片描述
在这里插入图片描述
2、新建Qt工程,把包含头文件
在这里插入图片描述
3、配置lib
在这里插入图片描述
4、dll放到exe目录下
在这里插入图片描述
5、编写客户端daim

int main(int argc, char *argv[])
{
    TreeBuilder builder;
    builder.test01();
    std::string tt=builder.getString(temp);
    qDebug()<<tt.c_str()<<endl;
}

6、运行看效果
在这里插入图片描述

三、原因分析和解决方法

1、原因是,字符集编码不一样,导致同一块内存两种含义,详细请看上一节讲解:https://blog.csdn.net/LittleLittleFish_xyg/article/details/83896107
2、如何解决呢?
既然c++的string有这个陷阱,解决方法为换一种传入的参数,改为unsigned char *,内部再使用unsigned char *到string的转换(注意用char,跨平台还可能是陷阱)
在这里插入图片描述
请仔细查看修改后的实现
3、客户端代码

int main(int argc, char *argv[])
{
    unsigned char str_temp[]="world";
    TreeBuilder builder;
    builder.test01();
    unsigned char* tt=builder.getString(str_temp);
    char *buf = reinterpret_cast<char*>(tt);
    qDebug()<<"return:"<<buf<<endl;
}

4、运行结果:

在这里插入图片描述

四、new对象产生的坑(遗留的bug,还没有找到解决方法)

描述:dll中使用了new操作符,并在dll中使用该指针,vs工厂调用dll能正常使用dll中的指针,但是Qt调用vs的dll不正常,于是将vs的dll和Qt进程联调进入dll的运行代码中发现,new出来并赋值后的内存全部为空,导致不可收拾的灾难。
个人理解:dll中的new实际上是exe的进程地址空间(这方面的知识可以在window核心编程的资料中看到),即vs工程exe调用dll时,dll中new出来的地址,是vs工程的进程地址,而Qt调用dll时是qt进程的地址,由于两种进程地址存在差异导致内存不能正常读取,Qt编码UTF-8,vs的是Unicode。当vs编译dll时候,认为你用Unicode的方式找到这个内存,而qt调用的dll的时候,却根据utf-8的内存来读写,dll中new出来的地址A,在qt进程确是对应B的地址位置,这时候还查看A地址,当然是有问题的(对逻辑地址的理解还不够,不知道是否正确,仅供参考)
如有大神指导一下这个bug的解决方法,实在感激不尽!因为这个bug的缘故,导致我放弃VS写这个sdk,改用Qt。

五、总结

跨平台一定要谨慎,能不夸尽量不跨,当然高手另当别说,对于新手各种细节不理解,出现各种问题不知如何寻求答案,经常一个小问题导致好几天没有进度。本来是想解救一下bug,却发现还留了一个坑,最后还是走了迁移代码的路!
下一节介绍Qt工程如何联调vs的dll工程

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值