Qt 插件系统所应当解决的最大的一个问题就是交互:包括主程序与插件的交互以及插件与主程序的交互。另外还有一个情况是插件之间的交互,这种情况比较罕见——我们一般不会将插件依赖于其它插件之上(因为我们不能确定这个插件存不存在),除非是非常重大的插件才支持自己的插件,并且这种情况十分类似主程序与插件之间的交互,只要把支持插件的插件理解为主程序就好了。
主程序如果需要使用插件提供的函数——比如在 OrbitsWriter 中,不同的插件提供了针对不同博客系统的 API 调用,主程序在向博客系统远程发表文章时,就必须调用插件对应的函数——这种情况就是最简单的情况:只需要将插件对象(QPluginManager::instance() 获得的对象)转换成接口,就可以调用响应的函数了。
前面我们的例子代码中,调用了插件对象的 name() 函数,就属于这种情况。
由于我们使用 C++ 编程,函数一般作为对象的成员,因此,插件需要调用对象成员函数的话,只需要能够获得对象就可以了。
调用主程序对象同调用一般对象没有区别。首先需要引用到对象的头文件,然后就可以调用。 这里需要注意的是,我们想要导出的对象必须使用 Q_DECL_EXPORT 宏进行修饰。而这个宏要求必须是一个共享库。也就是说,如果你的主程序有对象需要在插件中使用,那么,这些对象必须位于一个共享库中,不能在可执行文件中。
比如,我们希望提供一个类似日志的工具 Logger,这个 Logger 必须位于一个共享库中,并且使用 Q_DECL_EXPORT 宏修饰。然后,我们需要生成可执行文件时,需要连接这个库。
鉴于 Qt 插件框架的限制(插件只能以纯 C++ 接口的形式提供,不允许将这个接口继承 QObject),我们无法定义插件必须提供的信号槽。如果需要将主程序与插件对象进行信号槽连接,需要在接口中提供一个类似 getObject() 的函数,其返回值是一个 QObject *。这样,让插件将所需要进行信号槽连接的对象返回,从而完成与主程序的 connect() 函数。
联系客服