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

如何去實現一個動態插件
1 定義接口類:
1.1.定義共同接口(純虛類):
程序要能感知插件,需要程序和插件共同遵守某種規則。于是需要在主程序中定義一個共同的接口,該接口直接和插件類交流;
本例中定義一個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.主程序部分:
主程序部分動態加載插件的代碼如下:
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()測試插件是否給出了相應接口并進行類型轉換,轉換成接口對象指針.
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系統,將使用QContactPluginInterface這個接口。
3.3.輸出插件
Q_EXPORT_PLUGIN2(pluginXX, PluginXX);
使用宏 Q_EXPORT_PLUGIN2()是讓Qt知道PluginXX是一個插件,第一個參數是插件的名字,第二個參數是庫的名字,所以二者經常是相同的。
3.4.構建插件.
#pluginXX.pro
TEMPLATE = lib
CONFIG += plugin
INCLUDEPATH += ../XX
HEADERS = pluginXX.h
SOURCES = pluginXX.cpp
DESTDIR = ../
由以上.pro文件,Qt會自動將其編譯為動態插件,在主程序運行時動態加載。