zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    将Excel文件转换为Html
    怎样录制屏幕并将结果保存为Gif
    Spire.Pdf 的各种操作总结
    在C#中使用Spire.doc对word的操作总结
    使用Spire.Barcode程序库生成二维码
    【BZOJ1304】[CQOI2009]叶子的染色(动态规划)
    【BZOJ1303】[CQOI2009]中位数图(模拟)
    【BZOJ1297】[SCOI2009]迷路(矩阵快速幂)
    【BZOJ1296】[SCOI2009]粉刷匠(动态规划)
    【BZOJ1295】[SCOI2009]最长距离(最短路)
  • 原文地址:https://www.cnblogs.com/foohack/p/7588626.html
Copyright © 2011-2022 走看看