Распространение пользовательских плагинов Qt в комплекте приложений OSX - PullRequest
1 голос
/ 29 декабря 2010

Я создаю специальное приложение, в котором определенные части функциональности разделены на плагины Qt. Это работало довольно хорошо, используя QPluginLoader и qobject_cast, но до сих пор я использовал жестко запрограммированный абсолютный путь (не хотел усложнять вещи, прежде чем он заработал!).

Я близок к необходимости развертывания приложения на других машинах, поэтому я решил попробовать упаковать плагины в комплект приложений (я делаю это в основном для OSX). Потребовалось некоторое исследование, но вот что я придумал:

Файл MyApp.pro:

# ...

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 ...

Поэтому я добавляю путь к плагину к путям поиска в библиотеке:

main.cpp:

// ...

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? Есть что-то, что я просто делаю тупо неправильно? (Я предполагаю и надеюсь, что это более вероятно)


Дополнительное примечание:

Если я изменю plugins.path в файле MyApp.pro на Contents/MacOS, libMyPlugin.dylib получит вывод рядом с MyApp, и все будет работать нормально. Если я все равно так поступлю, я с удовольствием продолжу это делать.

Но в документации Qt показаны подключаемые модули Qt (qtjpeg и аналогичные), развертываемые в каталоге Contents/plugins, и аналогичный метод добавления каталога в путь к библиотеке QApplication.

1 Ответ

1 голос
/ 29 декабря 2010

Я храню плагины в application.app / Contents / plugins и использую следующий код для получения каталога плагинов:

...    
#elif defined(Q_OS_MAC)
    QDir pluginsDir = QDir(qApp->applicationDirPath());
    pluginsDir.cdUp();
    pluginsDir.cd("plugins");
#else
...

Теперь у вас есть правильный путь к директории плагинов, и вы можете загрузить плагин. У меня также есть файл qt.conf в application.app / Contents / Resources со следующим содержимым:

[Paths]
Plugins = plugins
...