如何在MeeGo Qt應(yīng)用程序中加載插件
QT 插件簡介
什么是插件
插件機(jī)制是一種擴(kuò)展現(xiàn)有程序的機(jī)制。插件允許第三方開發(fā)者在無需訪問主程序源代碼的情況下來擴(kuò)展該程序。插件能夠應(yīng)用的各項服務(wù),包括提供加載方式,使插件可以加載到應(yīng)用程序和網(wǎng)絡(luò)傳輸協(xié)議中,從而和插件進(jìn)行數(shù)據(jù)交換等。簡而言之,插件是提供特定接口的庫。
QT插件的兩種類型:
Qt Plugin和其他類型的插件一樣,是一種計算機(jī)應(yīng)用程序,它和主應(yīng)用程序(host application)互相交互,以提供特定的功能。應(yīng)用程序支持Plugin有許多原因,一些主要原因包括:使得第三方開發(fā)者有能力擴(kuò)展應(yīng)用程序,以提供無法先期預(yù)料的特色;減小應(yīng)用程序的大小;由于軟件版權(quán)之間的不兼容性將源代碼和應(yīng)用程序分享。Qt Plugin 分動態(tài)插件和靜態(tài)插件兩種。
1.靜態(tài)插件能夠靜態(tài)的鏈接到應(yīng)用程序,使得部署更少出錯,但是應(yīng)用程序重新構(gòu)建和發(fā)布時難以增加新的功能;
2.動態(tài)插件是更常用到和更靈活的方式,可以單獨發(fā)布,并且可以在運行時檢測和加載;
QT插件的實現(xiàn)步驟

如何去實現(xiàn)一個動態(tài)插件
1 定義接口類:
1.1.定義共同接口(純虛類):
程序要能感知插件,需要程序和插件共同遵守某種規(guī)則。于是需要在主程序中定義一個共同的接口,該接口直接和插件類交流;
本例中定義一個QContactPlugin interface
//QContactPluginInterface.h
#include
class QContactPluginInterface
{
public:
virtual ~ QContactPluginInterface () {}
virtual int getContact(int v) = 0;
};
1.2.使用宏Q_DECLARE_INTERFACE()
在QContactPluginInterface.h中添加以下代碼:
Q_DECLARE_INTERFACE(QContactPluginInterface, "com.intel.Plugin. QContactPluginInterface ");
Q_DECLARE_INTERFACE定義在在qobject.h中,用來告訴Qt meta-object system 這個接口名稱.
2.主程序部分:
主程序部分動態(tài)加載插件的代碼如下:
QDir pluginsDir(qApp->applicationDirPath());
foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();
if (plugin) {
QContactPluginInterface *interface = qobject_cast(plugin);
if (interface) {
qDebug()< getContact (10);
}
}
}
以上這段代碼主要包含以下幾個步驟:
2.1.到指定路徑搜索插件
QDir pluginsDir(qApp->applicationDirPath());
foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
2.2.檢測并加載插件.
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
2.3.測試插件是否有效
使用 qobject_cast()測試插件是否給出了相應(yīng)接口并進(jìn)行類型轉(zhuǎn)換,轉(zhuǎn)換成接口對象指針.
QContactPluginInterface *interface = qobject_cast(plugin);
if (interface) {
qDebug()< getContact (10);
}
#p#
3.編寫插件:
pluginXX.h
//Exampel, pluginXX.h
#include
#include " QContactPluginInterface.h"
class PluginXX:public QObject, public QContactPluginInterface
{
Q_OBJECT
Q_INTERFACES(QContactPluginInterface)
public:
PluginXX(QObject *parent=NULL);
int getContact (int v);
};
pluginXX.cpp
// Exampel pluginXX.cpp
#include "pluginXX.h"
PluginXX::PluginXX(QObject *parent)
:QObject(parent)
{
}
int PluginXX::getContact(int v)
{
//todo
return XXNumber;
}
Q_EXPORT_PLUGIN2(pluginXX, PluginXX);
以上這段代碼主要包含以下幾個步驟:
3.1.聲明插件類,
#include
#include " QContactPluginInterface.h"
class PluginXX:public QObject, public QContactPluginInterface
這個類繼承QObject 類和接口類,同時注意,需要將接口類的頭文件包含。
3.2.使用宏Q_INTERFACES()
Q_INTERFACES(QContactPluginInterface)
Q_INTERFACES 使用在定義接口類時通過Q_DECLARE_INTERFACE聲明過的接口。它同樣是用來告訴Qt的moc系統(tǒng),將使用QContactPluginInterface這個接口。
3.3.輸出插件
Q_EXPORT_PLUGIN2(pluginXX, PluginXX);
使用宏 Q_EXPORT_PLUGIN2()是讓Qt知道PluginXX是一個插件,第一個參數(shù)是插件的名字,第二個參數(shù)是庫的名字,所以二者經(jīng)常是相同的。
3.4.構(gòu)建插件.
#pluginXX.pro
TEMPLATE = lib
CONFIG += plugin
INCLUDEPATH += ../XX
HEADERS = pluginXX.h
SOURCES = pluginXX.cpp
DESTDIR = ../
由以上.pro文件,Qt會自動將其編譯為動態(tài)插件,在主程序運行時動態(tài)加載。