利用QT_DEBUG_PLUGINS检查Qt的插件问题

  Qt的编程中包含了插件模式,使得程序的扩展性非常好,但插件的动态加载的检查也比较严格,这次编译数据库驱动插件就碰到了不少问题。实际上,可以在系统的环境变量中设置QT_DEBUG_PLUGINS=1,再执行程序加载插件时,再系统控制台上会输出许多加载插件时的调试信息,可以清楚的看到系统尝试加载了哪些插件,哪些是成功的,哪些没有成功,原因是什么都写的比较清楚。因此,如果自己编译的插件库无法加载,可以用这个方式检查以下到底是哪里的问题。

无法加载的原因基本有3种:
    1. 编译的插件库没有放在正确的目录下,程序根本没找到;
    2. 插件库运行需要其他库的支持(比如数据库驱动插件,需要额外的相关数据库连接库),如果系统没有找到这些相关库,虽然可以找到你的插件,同样会无法加载;

    3. Build Key不兼容的问题,也就是说主程序编译的环境和插件编译的环境不兼容,导致插件和主程序可能无法调用,因此Qt也无法加载这些插件。


关于QPluginLoader的加载和卸载


    我们知道Qt的插件系统中通过QPluginLoader类来动态加载插件库,但对于具体的动态加载和卸载机制不是很清楚,因此花了点时间详细研究了QPluginLoader的源码,对于QPluginLoader类有些新的认识,记录如下,供参考。

    1. QPluginLoader在后台是通过QLibraryPrivate类完成加载库操作的,这与QLibrary类是一样的;

    2. 多个QPluginLoader的实例如果加载同一个插件库,那么其后台的库是同一个,也就是说多个QPluginLoader的实例并不会导致同一个动态库被多次加载;

    3. 在QPluginLoader对象被析构时,其加载的动态库也不会被卸载;

    4. QPluginLoader的load函数会在执行instance时自动执行,一般不需要直接执行;(参考文档中有提到)

    5. 卸载插件需要调用unload函数执行,但如果有多个实例加载(load)了同一个插件库,那么只有在最后一个实例执行unload后才能将动态库卸载,前几个实例的unload方法都会返回false,动态库也不会被卸载。


在QT框架下开发MFC主程序的一个插件遇到的问题


前阵子需要为一个软件(基于MFC框架或WinAPI开发)开发一个插件, 由于个人一直都是用的Qt框架写程序, 所以也理所当然的沿用了Qt。但是在调试时, Qt的信号/槽机制,以及一些定时器事件都无法执行和触发. 经过了学习文档, google学习等一番折腾之后, 搞清楚了原委: 原来Qt中的信号/槽响应机制, 以及定时器等这些功能都是需要通过QApplication的实例来进行消息分配, 如果没有QApplication的实例, 也就没有这些功能了. 而我们只是开发第三方软件的一个插件, 做成动态库形式, 也没有创建QApplication的实例, 而主程序里也不会有QApplication的实例, 所有就会有上述的问题.


  对于这个问题, 网上搜索到一个解决方案: 就是Qt solutions里的QtWinMigrate. 但是我下载来, 试用了一下, 没有成功. 因为时间问题也没有仔细研究,最后的方案是: 在该插件中涉及到Socket通讯的部分(前面提到的信号/槽机制和定时器时间等都是为了执行Socket通讯)改用Windows SOCKET API来编写.



你可能感兴趣的:(QT转载博文)