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. [转]QT QDateTime类、QTimer类

    QDateTime类,头文件#include <QDateTime> 可以使用QDateTime类来获得系统时间.通过QDateTime::currentDateTime()来获取本地系统 ...

  2. weblogic——服务器搭建与配置

    本次操作的内容:weblogic服务器搭建与配置服务 本次操作是主要围绕如何搭建weblogic服务器及配置服务,总共有两大步骤,可划分为六个小步骤: 选取已有环境,准备weblogic压缩包 安装w ...

  3. IIS6 Gzip 网页GZIP压缩(转)

    现在主流浏览器基本都支持 Gzip 压缩,因此这也成了 WebServer 优化策略的一种常规手段.启用压缩后能有效减少网页传输数据大小,使得有限带宽能提供更多的请求,并在一定程度上提高了网页 &qu ...

  4. 如何查看Isilon节点的硬件信息?

    Isilon节点虽然是一个Linux,但是很多linux下常用的命令都没有,比如说看内存的.笔者经过试验,列出了一些可用的命令. 查看硬件状态 isi_hw_status 查看内存 sysctl hw ...

  5. AOP AspectJ 字节码 示例 Hugo MD

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

  6. 《JavaScript语言精粹》笔记

    0.JavaScript的简单数据类型包括数字.字符创.布尔值(true/false).null和undefined值,其它值都是对象. 1.JavaScript只有一个数字类型,它在内部被表示为64 ...

  7. 设置虚拟机IP

    重启虚拟机 重启后,查看虚拟机IP ip a 虚拟机已有自己的IP 输入虚拟机用户

  8. Java复习3-类的继承

    前言 本次学习面向对象设计的另外一个基本概念:继承(inheritance).这是Java程序设计中的一项核心技术.另外,还要学习反射(reflection)的概念. 继承 类.超类.子类 publi ...

  9. 协程(Coroutine)并不是真正的多线程

    自:http://www.zhihu.com/question/23895384 说到Coroutine,我们必须提到两个更远的东西.在操作系统(os)级别,有进程(process)和线程(threa ...

  10. 微信小程序 - 自定义switch切换(示例)

    点击下载:switch示例 ,适用于表单,官方switch 说明 .