windows DLL中使用COM的注意事项
windows的DLL开发是有需要注意的地方的,不然会造成一些问题。由于我最近的使用不当,又造成了问题,虽然之前有写过一篇笔记, http://www.cnblogs.com/foohack/p/6645919.html 文章指出了在DLL中不能调用CoInitilazie
等初始化COM库的API。但是自己还是没有深刻理解。因为之前的项目只有一个线程,也就是主线程,主线程加载了一个DLL插件,DLL中有个Timer来定时在后台运行任务,任务需要使用wmic命令行提供的COM接口来
采集我所需要的数据,这样做是没问题的,就像贴出来的链接那篇文章所描述的一样,不需要初始化COM库了,因为主线程在加载DLL的那一刻已经初始化了COM库,我只用调用CoCreateInstance这个API创建COM接口的实例就可以了。
但是,最近的项目需要用Qt插件机制编写多个插件,关于数据采集那个插件需要用一个新的后台线程来运行Timer的定时任务,不然会阻塞Qt的UI主线程。由于采用了多个线程,我就没有注意到一个小细节上,
因为加载后台数据采集插件的线程还是主线程,只是加载完毕以后,我才通过Qt的moveToThread把任务对象移动到Qt新建的后台线程中的,所以这个新线程在调用COM接口的时候出错了,原因是新的后台线程没有初始化COM库,
DLL本质上还是主线程加载的。所以当然,COM接口是不会调用成功的了。所以,我就在运行DLL的后台线程里面有加入了CoInitializeEx等COM库的初始化函数,果然,COM接口调用成功了,并且能采集数据了,
之后神奇的事情发生了,看了日志,只有第一次调用的COM接口成功返回了数据,后面的COM接口的调用全部都失败了!! 后来查了MSDN的CoInitializeEx的函数说明,才知道,一个线程要使用COM接口,CoInitializeEx这个API有且只能在一个线程中调用
一次。不能调用两次,也不能调用0次, 由于我调用COM接口是封装在一个对象中的,在类的构造函数中调用了CoInitializeEx,所以新的对象反复初始化,就会导致该函数多次调用,导致后续的COM接口调用都不成功,后来我就把CoInitializeEx和CoInitializeSecurity提取出来,采用QThread的信号槽机制,在后台线程启动的那一刻,(接收started信号),来初始化COM库,这样在这个线程中对CoInitializeEx的调用就有且仅有一次了,所以后续的COM接口的调用都返回成功了。
references:
https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx
windows DLL中使用COM的注意事项的更多相关文章
- System.Windows.Forms.AxHost.InvalidActiveXStateException”类型的异常在 ESRI.ArcGIS.AxControls.dll 中发生,但未在用户代码中进行处理
private void CopyAndOverwriteMap() { //IObjectCopy接口变量申明 IObjectCopy objectCopy = new ObjectCopyClas ...
- windows系统中的dll的作用详细解释
什么是.DLL文件? DLL 是一个包含可由多个程序同时使用的代码和数据的库.例如,在 Windows 操作系统中,Comdlg32 DLL 执行与对话框有关的常见函数.因此,每个程序都可以使用该 D ...
- c++MFC工程修改在共享DLL中使用MFC为使用标准Windows库的解决办法
由于创建MFC工程时,默认是在共享DLL中使用MFC,如果将此选项改成使用标准Windows库,会报如下错误 c:\program files\microsoft visual studio 9.0\ ...
- 怎样从一个DLL中导出一个C++类
原文作者:Alex Blekhman 翻译:朱金灿 原文来源: http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx 译 ...
- 在系统启动时,Windows Vista 中、 在 Windows 7 中,Windows Server 2008 中和在 Windows Server 2008 R2 中的 497 天后未关闭 TIME_WAIT 状态的所有 TCP/IP 端口
在系统启动时,Windows Vista 中. 在 Windows 7 中,Windows Server 2008 中和在 Windows Server 2008 R2 中的 497 天后未关闭 TI ...
- asp.net教程:编译错误同时存在于不同dll中
asp.net 编译错误类型“同时存在于”不同的dll中. 出现这种错误大概有三种情况: 1.ASPX页面,一个*.ASPX,对应着一个*.cs文件,两者其实是一个文件,通过两者实现代码分离,每个*. ...
- 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离
在某国外大型汽车公司BI项目中,有一个子项目,需要通过大屏幕展示销售报表,程序需要自动启动和关闭.开发人员在开发过程中,发现在Win7的service中不能直接操作UI进程,调查过程中,发现如 ...
- DLL中传递STL参数(如Vector或者list等)会遇到的问题[转载]
最近的一个项目中遇到了调用别人的sdk接口(dll库)而传给我的是一个vector指针,用完之后还要我来删除的情况.这个过程中首先就是在我的exe中将其vector指针转为相应指针再获取vector中 ...
- [转]解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离
服务(Service)对于大家来说一定不会陌生,它是Windows 操作系统重要的组成部分.我们可以把服务想像成一种特殊的应用程序,它随系统的“开启-关闭”而“开始-停止”其工作内容,在这期间无需任何 ...
随机推荐
- Learning to rank相关的pointwise,pairwise,listwise
论文分享--- >Learning to Rank: From Pairwise Approach to Listwise Approach 学习排序 Learning to Rank 小结 [ ...
- vRealize Automation部署虚机如果出错怎么办?
以下地方的日志可以查看: 1. Requests –> Choose my request -> View Detail –> Execution Information. 2. I ...
- git版本还原
本地还原 在确认需要进行版本还原以后, 打开GIT BASH 输入: git reset --hard ad76ebf5ba8fb12bc38300ee99db478b332c1f7b 此操作成功以后 ...
- POJ 2280 Amphiphilic Carbon Molecules 极角排序 + 扫描线
从TLE的暴力枚举 到 13313MS的扫描线 再到 1297MS的简化后的扫描线,简直感觉要爽翻啦.然后满怀欣喜的去HDU交了一下,直接又回到了TLE.....泪流满面 虽说HDU的时限是2000 ...
- SpringMVC验证框架Validation特殊用法
基本用法不说了,网上例子很多,这里主要介绍下比较特殊情况下使用的方法. 1. 分组 有的时候,我们对一个实体类需要有多中验证方式,在不同的情况下使用不同验证方式,比如说对于一个实体类来的id来说,保存 ...
- WIN10系统如何关闭用户账户控制
在底部搜索框中输入UAC,打开用户账户控制设置 更改为从不通知即可
- Android开发点滴 - 如何使按钮水平垂直居中且始终占据屏幕宽度一半
问题描述: 如何使按钮水平垂直居中且始终占据屏幕宽度一半 效果如下: 竖屏: 横屏: 解决方案: 使用线性布局,指定线性布局的总权重(weightSum)为1, 指定按钮的权重为其一半即0.5 布局代 ...
- input[type="checkbox"]与label对齐
项目中遇到文字与 checkbook 无法水平对齐, 源码如下: <div align='center'> <input type="checkbox" id=& ...
- fread/fwrite
fread/fwrite第二个参数和第三个参数的区别以及与返回值的关系 size_t fwrite_unlocked(const void * __restrict ptr, size_t size, ...
- ubuntu下配置华为交换机s2016
因为笔记本没有RS232口,只有装有ubuntu的服务器上有RS232口,于是登录ubuntu 配置连接. 这里使用minicom,当然,Ubuntu源还有个图形界面的gtkterm, cutecom ...