# define Q_DECLARE_INTERFACE(IFace, IId) template <> inline const char *qobject_interface_iid<IFace *>() { return IId; } template <> inline IFace *qobject_cast<IFace *>(QObject *object) { return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : 0)); } \ // qt_metacast通过插件的IID来映射接口类的指针。一个IID绑定一个接口类 template <> inline IFace *qobject_cast<IFace *>(const QObject *object) { return reinterpret_cast<IFace *>((object ?const_cast<QObject *>(object)->qt_metacast(IId) : 0)); }
举例,
头文件 MyPluginInterface.h 中虚拟接口类的定义例如以下
#include <QtPlugin> #define QtPluginDemo_iid "org.qt-project.Qt.PluginDemo" // 定义接口的IID class MyPluginInterface { public: virtual ~MyPluginInterface(){} virtual void showPluginName(); }; Q_DECLARE_INTERFACE ( MyPluginInterface, QtPluginDemo_iid ) ;
class MyPlugin : public QObject, public MyPluginInterface { Q_OBJECT // Q_PLUGIN_METADATA ( IID QtPluginDemo_iid FILE "MyPlugin.json") Q_PLUGIN_METADATA ( IID QtPluginDemo_iid) Q_INTERFACES(MyPluginInterface) public: void showPluginName(); };
... ... static const qt_meta_stringdata_MyPlugin_t qt_meta_stringdata_MyPlugin = { { QT_MOC_LITERAL(0, 0, 8) }, "MyPlugin" }; ... ... void *MyPlugin::qt_metacast(const char *_clname) // Q_DECLARE_INTERFACE宏就是利用这个函数实现的qobject_cast类型映射 { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_MyPlugin.stringdata)) // 假设_clname与类的名称MyPlugin匹配,返回有效指针 return static_cast<void*>(const_cast< MyPlugin*>(this)); if (!strcmp(_clname, "MyPluginInterface")) // 假设_clname与接口类的名称MyPluginInterface匹配,返回有效指针 return static_cast< MyPluginInterface*>(const_cast< MyPlugin*>(this)); if (!strcmp(_clname, "org.qt-project.Qt.PluginDemo")) // 假设_clname与接口类的IID匹配,返回有效指针。 // 这里就用到了调用Q_DECLARE_INTERFACE宏时使用的IID參数 // 并且,Q_DECLARE_INTERFACE宏的代码中也是利用IID映射实现的qobject_cast return static_cast< MyPluginInterface*>(const_cast< MyPlugin*>(this)); return QObject::qt_metacast(_clname); } ... ...
原文:http://www.cnblogs.com/yutingliuyl/p/7231178.html