【大型软件开发】浅谈大型Qt软件开发(四)动态链接库的宏冲突问题、COM组件开发的常...
source link: https://www.cnblogs.com/Leventure/p/17107739.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
最近工作的时候有一个链接库的对接工作,在对接时发生了一些小问题,这篇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内,就不会被析构了,除非你自己提供了一个析构的方法。
Recommend
-
6
浅谈软件开发的三个特点 06月 30日, 2020 1 minute read 最近大老板让开发一个很看好的产品,当然大老板想要开发的产品,大家都一定觉得是有前途的产品。经过辛苦的996了2个月开发,终于做出来了第一个版本。现在自己...
-
5
CMake 动态链接库绝对路径问题 今天这篇文章算是对 【CMake 系列】(五)安装、打包与导出 的一个补充。其实我本打算跟上篇文章放在一起,毕竟都属于动...
-
2
浅谈 RISC-V 软件开发生态之 IDE浅谈 RISC-V 软件开发生态之 IDE 发表于...
-
5
Android动态加载so文件(解决so文件冲突) – Android开发中文站你的位置:Android开发中文站 > Android开发 >
-
1
机器学习与传统软件开发的冲突与融合 - alepiad 在过去...
-
4
Linux动态链接库符号冲突解决 2022-11-22...
-
6
【大型软件开发】浅谈大型Qt软件开发(一)开发前的准备——在着手开发之前,我们要做些什么? ...
-
1
【大型软件开发】浅谈大型Qt软件开发(二)面向未来开发——来自未来的技术:COM组件。我如何做到让我们的教学模块像插件一样即插即用...
-
3
【大型软件开发】开发日志(五).net框架与C++的融合:CLR——C++调用C#的DLL ...
-
9
Opentelemetry社区在gRPC的几个链接问题(静态库和动态库混用,musl工具链,符号裁剪)
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK