Qt 插件机制以及插件中几个重要的宏

来源:互联网 发布:郑州公交线路查询软件 编辑:程序博客网 时间:2024/06/06 01:56

简述:

Qt 插件类必须继承自 QObject 类和插件接口类。若没有 Q_DECLARE_INTERFACE 和 Q_INTERFACES 这两个宏,就无法对从插件中获取的实例指针进行 qobject_cast 映射。然后,可以通过 QPluginLoader 类调用插件类。


1、接口类


首先,定义一个纯虚类作为插件接口类

[cpp] view plain copy
  1. #include <QtPlugin>    
  2. #include <QString>    
  3.     
  4. class IMyPlugin    
  5. {    
  6. public:    
  7.     virtual QString Hello() = 0;    
  8. };    
  9.     
  10. Q_DECLARE_INTERFACE(IMyPlugin, "com.lidar.plugin.IMyPlugin")    


Q_DECLARE_INTERFACE 宏告诉Qt 这个纯虚类是一个插件接口类Q_DECLARE_INTERFACE 宏是与qobject_cast相关的。

第一个参数是接口类名,第二个参数是插件标志符,标识符是大小写敏感的且必须是唯一


2、实现类 


接着,是接口类的具体实现,即实现类。实现类必须继承自 QObject 插件接口类(也可以在插件接口类的时候就继承QObject)。

每一个插件类都有一个独立的 IID 值。

[cpp] view plain copy
  1. class MyPlugin : public QObject, public IMyPlugin    
  2. {    
  3.     Q_OBJECT    
  4.     Q_PLUGIN_METADATA(IID "com.lidar.myplugin" FILE "C:/a.json")    
  5.     Q_INTERFACES(IMyPlugin)    
  6.       
  7. public:    
  8.     virtual QString Hello() Q_DECL_OVERRIDE;    
  9. };  

① Q_PLUGIN_METADATA  : Q_PLUGIN_METADATA  宏用于描述插件元数据,第一个参数 IID 必须的,同插件标识符一样,而第二个参数FILE是可选的,指定一个本地的 json 文件,该文件可以描述插件的相关数据信息


② Q_INTERFACES :若一个头文件或源文件中用到了 Q_INTERFACES 宏,那么在调用这个宏之前,必须存在一个 Q_DECLARE_INTERFACE 宏声明相应的接口(或者包含一个用 Q_DECLARE_INTERFACE 宏声明了该接口的头文件),MOC会检查这一点,因为它在为 Q_INTERFACES 宏生成代码时要用到Q_DECLARE_INTERFACE 宏的 IID 参数

Q_INTERFACES宏也是与qobject_cast相关,没有 Q_DECLARE_INTERFACE 和 Q_INTERFACES 这两个宏,就无法对从插件中获取的实例指针进行qobject_cast映射


③ Q_DECL_OVERRIDE :Q_DECL_OVERRIDE 宏来声明这是一个对虚函数进行定义的方法,编译器会验证该方法名是否是父类中所有的,如果没有则报错(这个类似 Java里的 @Override 注解)。


3、调用


最后,通过 QPluginLoader 类调用插件类。

[cpp] view plain copy
  1. {  
  2.     QPluginLoader loader("C:/MyPlugin.dll");    
  3.     if (loader.load())    
  4.     {    
  5.         QObject *obj = loader.instance();    
  6.         if (obj)    
  7.         {    
  8.             IMyPlugin *plugin = qobject_cast<IMyPlugin*>(obj);    
  9.             if (plugin)    
  10.             {    
  11.                 // 测试插件方法    
  12.                 qDebug() << plugin->Hello();    
  13.     
  14.                 // 输出插件元数据    
  15.                 qDebug() << loader.metaData();    
  16.             }    
  17.     
  18.             // 需要手动释放    
  19.             delete obj;    
  20.         }    
  21.     }    
  22. }