【大型软件开发】浅谈大型Qt软件开发(四)动态链接库的宏冲突问题、COM组件开发的常见问题
最近工作的时候有一个链接库的对接工作,在对接时发生了一些小问题,这篇FAQ是办公室写这个库的工程师戴工写的,这里记录一下:
一、编译工程时报链接错误“不允许dllimport静态数据成员的定义”
1.错误截图

2.错误原因分析
此错误是Q_OBJECT和Q_DECL_IMPORT宏共同作用时产生的结果。查询微软文档可知:静态数据成员无法在定义dllimport类的同一程序中指定定义。

这句话表明,导出类时,其静态成员不可被外部覆盖定义。举个例子,有导出类如下:

其中宏定义为:

根据微软关于dllimport的说明,类静态成员变量n不可被覆盖定义,即进行这样的操作

可以看到,对普通成员函数fun进行覆盖,仅仅发出了编译警告,但编译器并没有明确拒绝这种行为,但在对静态成员n进行覆盖定义时,编译器报错,拒绝了此行为。
回过头来看Q_OBJECT宏的定义:

发现静态成员staticMetaObject,根据QMAKE规则,QT编译时会对包含有Q_OBJECT宏的类进行一次moc工作,而moc_*.cpp中刚好拥有staticMetaObject的定义操作:

因此,Q_DECL_IMPORT(即dllimport)宏导出的类中包含了Q_OBJECT宏时,违反了编译器规则,因此无法完成编译。
3.修改策略
(1)修改导出类,如果导出类中含有Q_OBJECT宏,保留导出定义,去除导入定义;
(2)去除Q_DECL_IMPORT声明。由QT向导生成的宏声明文件中,有条件编译控制宏BUILD_STATIC,当工程中定义了该宏时,便可取消Q_DECL_IMPORT宏的导入声明;也可以不定义BUILD_STATIC宏,而是手动修改文件,去除Q_DECL_IMPORT宏。

(3)去除/注释Q_OBJECT宏。导入类时,可以在工程代码中将导入库头文件中的Q_OBJECT宏逐个注释。

(4)从工程中移除相关头文件。

二、创建dll导入类时报警告“QObject: Cannot create children for a parent that is in a different thread.”
1. 错误截图
略
2.错误原因分析
这可能是由于工程编译版本类型与链接库的类型不一致导致,比如工程当前为debug版本,但链接库编译生成版本为release
3.错误修改策略
将工程生成版本调整为与链接库版本一致
三、单例写法:
原先的单例写法比较简单,代码大概如下:
static Test&Test::Singleton(){
static Test Instance;
return Instance
}
这样的单例模式看上去还行,这个也是我之前常用的单例模式。但是这个在COM组件的开发中是不够安全的,原因也很简单~因为我们提交给COM组件的IDispatch是指针形式提交的,这个指针有可能会在外部被析构掉(只是提出一种可能,这里尚未测试和验证),所以这个单例模式是指针不安全的。
既然如此我们就需要修改一种比较好用且指针安全的单例模式。今天看了下小余的代码我感觉还挺好用的,拿过来抄一下:
static NetServer* NetServer::Singleton() {
static QMutex mutext;
static QSharedPointer<NetServer> inst;
if (Q_UNLIKELY(!inst)) {
if (!inst) {
inst.reset(new NetServer());
}
}
return inst.data();
}
这段代码就是用的QSharedPointer 智能指针对单例指针进行维护,这样只要主进程还在,这个单例的指针就会一直保存在QSharedPointer内,就不会被析构了,除非你自己提供了一个析构的方法。
【大型软件开发】浅谈大型Qt软件开发(四)动态链接库的宏冲突问题、COM组件开发的常见问题的更多相关文章
- [IC]浅谈嵌入式MCU软件开发之中断优先级与中断嵌套
转自:https://mp.weixin.qq.com/s?__biz=MzI0MDk0ODcxMw==&mid=2247483680&idx=1&sn=c5fd069ab3f ...
- 浅谈大型web系统架构
动态应用,是相对于网站静态内容而言,是指以c/c++.php.Java.perl..net等服务器端语言开发的网络应用软件,比如论坛.网络相册.交友.BLOG等常见应用.动态应用系统通常与数据库系统. ...
- 转:浅谈大型web系统架构
浅谈大型web系统架构 动态应用,是相对于网站静态内容而言,是指以c/c++.php.Java.perl..net等服务器端语言开发的网络应用软件,比如论坛.网络相册.交友.BLOG等常见应用.动态应 ...
- 浅谈OA办公软件市场行情
3.原文:http://www.jiusi.net/detail/472__776__3999__1.html 关键词:oa系统,OA办公软件 浅谈OA办公软件市场行情 中国的OA办公软件市场历经20 ...
- 【ZZ】浅谈大型web系统架构 | 菜鸟教程
浅谈大型web系统架构 http://www.runoob.com/w3cnote/large-scale-web-system-architecture.html
- 浅谈关于QT中Webkit内核浏览器
关于QT中Webkit内核浏览器是本文要介绍的内容,主要是来学习QT中webkit中浏览器的使用.提起WebKit,大家自然而然地想到浏览器.作为浏览器内部的主要构件,WebKit的主要工作是渲染.给 ...
- springboot开发浅谈 2021/05/11
学习了这么久,本人希望有时间能分享一下,这才写下这篇浅谈,谈谈软件,散散心情. 这是本人的博客园账号,欢迎关注,一起学习. 一开始学习springboot,看了好多网站,搜了好多课程.零零落落学了一些 ...
- Android开发-浅谈架构(二)
写在前面的话 我记得有一期罗胖的<罗辑思维>中他提到 我们在这个碎片化 充满焦虑的时代该怎么学习--用30%的时间 了解70%该领域的知识然后迅速转移芳草鲜美的地方 像游牧民族那样.原话应 ...
- Python测试开发-浅谈如何自动化生成测试脚本
Python测试开发-浅谈如何自动化生成测试脚本 原创: fin 测试开发社区 前天 阅读文本大概需要 6.66 分钟. 一 .接口列表展示,并选择 在右边,点击选择要关联的接口,区分是否要登录, ...
- [置顶] 浅谈大型web系统架构
转载原文:http://blog.csdn.net/dinglang_2009/article/details/6863697 分类: 大规模Web 2.0架构 2011-10-11 18:27 12 ...
随机推荐
- Spring Boot 中使用 tkMapper
说明:基于 MyBatis 有很多第三方功能插件,这些插件可以完成数据操作方法的封装.数据库逆向工程的生成等. tkMapper 和 MyBatis-plus 都是基于 MyBatis 提供的第三方插 ...
- [leetcode] 994. Rotting Oranges
题目 You are given an m x n grid where each cell can have one of three values: 0 representing an empty ...
- TreeUtils工具类一行代码实现列表转树 实战Java8 三级菜单 三级分类 附视频
一.序言 在日常一线开发过程中,总有列表转树的需求,几乎是项目的标配,比方说做多级菜单.多级目录.多级分类等,有没有一种通用且跨项目的解决方式呢?帮助广大技术朋友给业务瘦身,提高开发效率. 本文将基于 ...
- VS 新版本无法打开旧项目问题处理
问题 最近想阅读 WorkflowCore 的源码,苦于代码量巨大,就想将项目回退到 Init Commit 版本 但是在回退版本后,工程内Project 显示已卸载 重新加载后 提示: 不支持 Th ...
- jquery组件解决option选项框的样式自定义方案
记录一下今天工作中遇到的一个需求和自行找到的解决办法 需求: 在原始的select选项框中的增加一个标识.(我想增加一个具有样式的span元素,试了半天在option里无法添加span,更别说具有样式 ...
- PP视频(PPTV聚力)web接口分析
前言 前几天我想看一个番剧, 正好搜索到了 PP视频,我才知道PP视频就是PPTV聚力,我想把番剧下载下来,结果发现视频竟然不是m3u8格式,而是多段mp4,所以简单的写了个脚本,可以在不登录的情况下 ...
- 解决一个mysql报错
问题描述 insert into btsync (key,title) values ('a','b'); ERROR 1064 (42000): You have an error in your ...
- go-carbon 1.5.1 版本发布, 修复已知 bug 和新增土耳其翻译文件
carbon 是一个轻量级.语义化.对开发者友好的golang时间处理库,支持链式调用. 目前已被 awesome-go 收录,如果您觉得不错,请给个star吧 github.com/golang-m ...
- 模板层之标签 自定义过滤器及标签 模板的继承与导入 模型层之前期准备 ORM常用关键字
目录 模板层之标签 if判断 for循环 自定义过滤器.标签及inclusion_tag(了解) 前期三步骤 自定义过滤器(最大只能接收两个参数) 自定义标签(参数没有限制) 自定义inclusion ...
- Redis——02 学习
Redis--02 前面了解了 Redis 以及在 Linux 的安装,下面了解一些 Redis 常用的命令. Redis 常用命令: Redis 是 Key-Value 形式,Key 为字符串类型, ...