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的注意事项的更多相关文章

  1. System.Windows.Forms.AxHost.InvalidActiveXStateException”类型的异常在 ESRI.ArcGIS.AxControls.dll 中发生,但未在用户代码中进行处理

    private void CopyAndOverwriteMap() { //IObjectCopy接口变量申明 IObjectCopy objectCopy = new ObjectCopyClas ...

  2. windows系统中的dll的作用详细解释

    什么是.DLL文件? DLL 是一个包含可由多个程序同时使用的代码和数据的库.例如,在 Windows 操作系统中,Comdlg32 DLL 执行与对话框有关的常见函数.因此,每个程序都可以使用该 D ...

  3. c++MFC工程修改在共享DLL中使用MFC为使用标准Windows库的解决办法

    由于创建MFC工程时,默认是在共享DLL中使用MFC,如果将此选项改成使用标准Windows库,会报如下错误 c:\program files\microsoft visual studio 9.0\ ...

  4. 怎样从一个DLL中导出一个C++类

    原文作者:Alex Blekhman    翻译:朱金灿 原文来源: http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx 译 ...

  5. 在系统启动时,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 ...

  6. asp.net教程:编译错误同时存在于不同dll中

    asp.net 编译错误类型“同时存在于”不同的dll中. 出现这种错误大概有三种情况: 1.ASPX页面,一个*.ASPX,对应着一个*.cs文件,两者其实是一个文件,通过两者实现代码分离,每个*. ...

  7. 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

        在某国外大型汽车公司BI项目中,有一个子项目,需要通过大屏幕展示销售报表,程序需要自动启动和关闭.开发人员在开发过程中,发现在Win7的service中不能直接操作UI进程,调查过程中,发现如 ...

  8. DLL中传递STL参数(如Vector或者list等)会遇到的问题[转载]

    最近的一个项目中遇到了调用别人的sdk接口(dll库)而传给我的是一个vector指针,用完之后还要我来删除的情况.这个过程中首先就是在我的exe中将其vector指针转为相应指针再获取vector中 ...

  9. [转]解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

    服务(Service)对于大家来说一定不会陌生,它是Windows 操作系统重要的组成部分.我们可以把服务想像成一种特殊的应用程序,它随系统的“开启-关闭”而“开始-停止”其工作内容,在这期间无需任何 ...

随机推荐

  1. FileStream 的FileShare一点小认识

    C#读写文本文件一般都是用StreamWriter来实现(读书的时候就这样用,毕业后这几年基本也是这样干的),通常代码如下: using (StreamWriter sw = new StreamWr ...

  2. 如何在Windows版的ScaleIO的节点中添加磁盘

    嗯, 为什么会有这个问题呢? 因为我要安装ScaleIO 1.32, 在使用Installation manager完成初始安装之后, 需要将一些磁盘添加到ScaleIO的storage pool中. ...

  3. 异常捕获 UncaughtExceptionHandler MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. JavaScript 实现打印,打印预览,打印设置

    WebBrowser是IE内置的浏览器控件,无需用户下载. 一.WebBrowser控件 <object ID='WebBrowser' WIDTH=0 HEIGHT=0 CLASSID='CL ...

  5. VIM的buffers

    原文:http://ju.outofmemory.cn/entry/13522 重新在不同的 tab 中打开多个关闭的buffer 文件, https://stackoverflow.com/ques ...

  6. 浅谈压缩感知(九):正交匹配追踪算法OMP

    主要内容: OMP算法介绍 OMP的MATLAB实现 OMP中的数学知识 一.OMP算法介绍 来源:http://blog.csdn.net/scucj/article/details/7467955 ...

  7. Web UI 技术发展历程

    本文内容 纯文本和静态 HTML 页面 服务器端技术 插件技术--ActiveX.Applet 和 Flash Ajax 异步时代和基于 JavaScript 的 UI 技术 RIA--Adobe F ...

  8. 异步 JS: Callbacks, Listeners, Control Flow Libs 和 Promises【转载+翻译+整理】

    http://sporto.github.io/blog/2012/12/09/callbacks-listeners-promises/ 或 http://www.ruanyifeng.com/bl ...

  9. WIN10系统如何隐藏底部搜索框

    右击任务栏,搜索,可以切换三种模式,建议还是显示搜索图标,因为这个搜索还是能比较快速定位到系统功能的,只不过显示搜索框的话比较占地方,不方便

  10. Jquery遍历筛选数组的几种方法和遍历解析json对象|Map()方法详解

    Jquery遍历筛选数组的几种方法和遍历解析json对象|Map()方法详解 一.Jquery遍历筛选数组 1.jquery grep()筛选遍历数组 $().ready( function(){ v ...