我正在构建一个自定义应用程序,它将某些功能部分分离到Qt插件中。使用QPluginLoader
和qobject_cast
一直很好用,但到目前为止,我一直在使用硬编码的绝对路径(在我工作之前不想让事情变得复杂!)。
我已经接近需要将应用程序部署到其他计算机,所以我决定尝试将插件打包到应用程序包中(我主要是为OSX构建这个)。这需要一些研究,但这就是我想出来的:
# ...
macx {
plugins.path = Contents/Plugins
plugins.files = ../PluginDir-build-desktop/libMyPlugin.dylib
QMAKE_BUNDLE_DATA += plugins
}
这给出了一个很好的捆绑结构,看起来像这样:
MyApp.app
|
+- Contents
|
+- MacOS
| |
| +- MyApp
|
+- Plugins
| |
| +- libMyPlugin.dylib
|
... other support files ...
所以我将插件路径添加到库搜索路径:
// ...
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDir pluginsDir(a.applicationDirPath());
pluginsDir.cdUp();
pluginsDir.cd("Plugins");
a.addLibraryPath(pluginsDir.absolutePath());
// ...
return a.exec();
}
然后尝试加载插件,如下所示:
// ...
QPluginLoader pluginLoader;
pluginLoader.setFileName("libPhotoshopPlugin.dylib");
IMyPluginInterface* plugin = qobject_cast<IMyPluginInterface*>(pluginLoader.instance());
// ...
不幸的是,插件总是出现NULL。但是当我这样做时:
// ...
QPluginLoader pluginLoader;
pluginLoader.setFileName("../Plugins/libPhotoshopPlugin.dylib");
IMyPluginInterface* plugin = qobject_cast<IMyPluginInterface*>(pluginLoader.instance());
// ...
我得到的插件实例很好,一切正常。
为什么我必须在传递给QPluginLoader的文件名中指定路径?它不应该从QApplication
库路径中选择它吗?有什么我只是做愚蠢的错吗? (我猜测并希望这更有可能)
如果我将 MyApp.pro 文件中的 plugins.path 更改为Contents/MacOS
,则在MyApp旁边的libMyPlugin.dylib获取输出,一切正常精细。如果这是我应该这样做的方式,我会很乐意继续这样做。
但是Qt documentation显示了部署在Contents/plugins
目录中的Qt插件(qtjpeg和类似插件)以及用于将目录添加到QApplication
库路径的类似方法。
答案 0 :(得分:1)
我将插件存储在 application.app/Contents/plugins 中,并使用以下代码获取插件目录:
...
#elif defined(Q_OS_MAC)
QDir pluginsDir = QDir(qApp->applicationDirPath());
pluginsDir.cdUp();
pluginsDir.cd("plugins");
#else
...
现在你有了插件目录的正确路径,并且可以加载插件。我还在 application.app/Contents/Resources 中有一个 qt.conf 文件,其中包含以下内容:
[Paths]
Plugins = plugins