2016-04-25 90 views
2

我有一個Qt應用程序,允許自定義插件(使用QPluginLoader加載),這些插件可以實現一些接口,並使用Q_INTERFACES()宏聲明。Qt插件:有沒有辦法列出插件實現的所有接口?

如果你看看Qt的文檔鏈接如下,我說的是「低層次」的API: http://doc.qt.io/qt-5/plugins-howto.html

現在,這是我的問題:之後我加載插件與QPluginLoader,是有一種方法來枚舉它實現的所有接口?基本上,有沒有一種方法來枚舉插件在加載插件的主應用程序的Q_INTERFACES()宏中聲明的內容?

該應用程序目前適用於Qt4和Qt5,但只適用於Qt5的解決方案也是可以接受的。

+0

Qt明確地爲接口創建元數據,但我似乎沒有找到任何方式來遍歷它。 – dtech

+0

@ddriver元數據是以非常隱含的方式創建的:moc生成的代碼可以讓您將'QObject'轉換爲接口的實例,如果您知道接口的名稱。數據不會以任何其他方式保留:沒有任何接口列表:( –

+0

嗯,它必須存儲名稱的實際字符串,因爲元系統使用字符串文字和運行時查找,它只是一個元數據系統設計中嚴重遺漏的是,這些數據不是以一種更有用的方式構建的,我也不喜歡它爲所有事情生成的事實,如果你能指定你想要的元數據類型會更好 – dtech

回答

1

不幸的是,Qt不明確保留的接口:(

你能做的最好的是試圖通過投插件加載器返回的QObject * instance()給定一個給定的接口列表或者使用一個類名或。使用其IID,使用qt_metacast,即loader.instance()->qt_metacast("IFoo")如果結果不爲零,則給定的類或者實現接口

,您可以將每個接口類信息,然後你可以列舉出來:

class Impl : public QObject { 
    Q_OBJECT 
    Q_INTERFACES(IFoo IBar) 
    Q_CLASSINFO("Interface", "IFoo") 
    Q_CLASSINFO("Interface", "IBar") 
} 

QStringList interfaces(QObject * obj) { 
    QStringList result; 
    auto count = obj->metaObject()->classInfoCount(); 
    for (int i = 0; i < count; ++i) { 
    auto info = obj->metaObject()->classInfo(i); 
    if (strcmp(info.name(), "Interface") == 0) 
     result << QString::fromLatin1(info.value()); 
    } 
    return result; 
} 

如果您希望依賴此功能,您需要修改moc的副本以從Q_INTERFACES自動生成相關的類別信息。 IIRC它只是一些值得改變的行,我在某個時候做過類似的事情。

+0

如果你是一個實現插件的人,你可以在'InterfaceInfo'接口中添加一個'virtual QStringList interfaces()',並將其包含在每個插件中並手動實現。 – dtech

+0

@ddriver真的:) –

+0

謝謝你的答案! Qt沒有提供枚舉接口的方法太糟糕了。對於上下文,我的目標是從所有可用接口創建一個映射到所有實現它們的插件,因此任何想要與給定接口交互的人都可以查詢所有可用的插件。這樣,我可以(除其他外)實現插件依賴系統。 – Daniele

相關問題