Экземпляр QPluginLoader всегда возвращает null
Я занимаюсь разработкой приложения Qt. Хотя я запрограммировал много вещей GUI раньше, и сама инфраструктура не представляет проблемы, я ни разу не программировал (за пределами приложений С#.NET), которая имеет возможность загружать плагины. Проект, который я пытаюсь создать, имеет плагины как неотъемлемую часть его, и я думал, что структура Qt выглядела неплохо для этого, потому что она была почти повсеместно кросс-платформенной и, похоже, была очень приятной системой для плагинов.
Моя проблема заключается в следующем: я не могу заставить QPluginLoader.instance() возвращать что-либо, кроме нулевого значения.
Из моих чтений это происходит потому, что он не видит плагина. Я думаю, что я, вероятно, забываю что-то сделать, но я могу найти очень мало документации по написанию плагинов (есть примеры, но они не невероятно детализированы). Есть много примеров загрузки плагинов, и я думаю, что я делаю это правильно, но я действительно не нашел пример создания плагина.
Это то, что я сделал:
Используя Qt-Creator, я создал два проекта: оконное приложение, чтобы притворяться, что это приложение для моего плагина и проект общей библиотеки, чтобы притворяться плагином
В моем оконном приложении у меня есть файл заголовка следующим образом:
#ifndef PLUGININTERFACE_H
#define PLUGININTERFACE_H
#include <QtPlugin>
class QStringList;
class PluginInterface
{
public:
virtual ~PluginInterface() {};
virtual QStringList messages() const = 0;
};
Q_DECLARE_INTERFACE(PluginInterface,
"com.kevincuzner.LearningPlugins.PluginInterface/1.0")
#endif // PLUGININTERFACE_H
В приложении моей общей библиотеки я создал класс ATestPlugin (и это также значение TARGET проекта):
#ifndef ATESTPLUGIN_H
#define ATESTPLUGIN_H
#include "ATestPlugin_global.h"
#include "../LearningPlugins/PluginInterface.h"
#include <QStringList>
class ATESTPLUGINSHARED_EXPORT ATestPlugin : public PluginInterface, public QObject
{
Q_OBJECT
Q_INTERFACES(PluginInterface)
public:
ATestPlugin();
virtual QStringList messages() const
{
//this part is actually defined in the .cpp file, but I don't feel like pasting that here
QStringList ret;
ret << "foo" << "bar" << "noms" << "Hello";
return ret;
}
};
#endif // ATESTPLUGIN_H
В конце файла ATestPlugin.cpp я разместил Q_EXPORT_PLUGIN2(ATestPlugin, ATestPlugin)
Затем в основном файле main.cpp в основном методе я делаю следующее (& w указывает на главное окно):
QString text = QFileDialog::getOpenFileName(&w, "Get a file");
QPluginLoader loader(text);
QObject* plugin = loader.instance();
if (plugin)
{
QMessageBox msgBox;
msgBox.setText(text);
msgBox.exec();
}
Когда я запускаю программу и выбираю libATestPlugin.so из каталога сборки моего проекта библиотеки в появившемся диалоговом окне файла, я не вижу окна сообщений, что означает, что * плагин равен NULL. Раньше у меня всегда появлялся ящик сообщений и показывал имя выбранного файла, поэтому я знаю, что эта часть работает.
У кого-нибудь есть идеи относительно того, что мне нужно сделать, чтобы сделать мой плагин видимым для QPluginLoader?
После дальнейших экспериментов мне удалось загрузить плагин. Я чувствую себя застенчивым, говоря это, но это был классический случай RTFM.
Учебник по echo-плагину (который я не нашел до тех пор, пока я не опубликовал вопрос) не вносил некоторые изменения, которые должны были быть внесены в.pro файл в библиотеке, чтобы заставить его правильно объявить плагин:
Строка TARGET = ATestPlugin
должна была быть изменена на TARGET = $$qtLibraryTarget(ATestPlugin)
. После внесения этого изменения, появилось мое сообщение в приведенной выше программе, а позже, когда я запустил qobject_cast< PluginInterface* >(plugin)
а затем попросил PluginInterface->messages()
я получил список, который был реализован в отдельном классе.
Кроме того, я изменил порядок наследования, чтобы сначала поставить QObject, и поскольку он работает таким образом, я, вероятно, сохраню его (хотя, я не знаю, изменилось ли это).
Это не сработало для меня. Изменение предыдущего TARGET до $$ qtLibraryTarget (...) обеспечивает правильные расширения во время сборки на разных платформах.
У меня была такая же проблема с QPluginLoader. В нескольких словах я решил: я создаю библиотеку плагинов, скажем lib1.dll, которые используют некоторые вещи из lib2.dll. В моем приложении я пытаюсь загрузить lib1 через QPluginLoader.
QPluginLoader loader( adaptersDir.absoluteFilePath(fileName) );
AdapterInterface* adapterIface = qobject_cast<AdapterInterface*>(loader.instance());
В этом случае loader.instance() возвращает 0. Решение заключалось в том, чтобы скопировать lib2.dll в папку приложения, потому что приложение использует его для правильного загрузочного модуля lib1.
- Вопросы
- Shared-libraries
- Экземпляр QPluginLoader всегда возвращает null