Я решил переключить свое приложение проекта хобби (программу поиска по словарю) на архитектуру плагинов, чтобы в будущем можно было разрабатывать всевозможные словари для других языков. Приложение разработано в Visual C ++ с использованием Qt (5.0.2). Я добавил этот заголовок в код приложения, чтобы определить интерфейс для плагинов словаря:
// dict_plugin.h
#ifndef DICT_PLUGIN_H
#define DICT_PLUGIN_H
#include <QtPlugin>
class PluginInterface
{
public:
virtual ~PluginInterface() {}
virtual QString language() const = 0;
virtual class QWidget* ui() const = 0;
};
Q_DECLARE_INTERFACE(PluginInterface, "pl.ksmvision.winona.PluginInterface")
#endif // DICT_PLUGIN_H
Затем я создал новый проект из шаблона «Библиотека Qt» для самого плагина (используя надстройку Qt Visual Studio), который используется для создания библиотеки DLL. Основной заголовочный файл выглядит так:
#ifndef JP_PLUGIN_H
#define JP_PLUGIN_H
// created by the template to define Q_DECL_EXPORT
// and _IMPORT macros but the plugin engine takes
// care of that (I think)
//#include "jp_plugin_global.h"
#include <QObject>
#include <QtPlugin>
#include <dict_plugin.h>
class JpPlugin : public QObject, public PluginInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "pl.ksmvision.winona.JpPlugin")
Q_INTERFACES(PluginInterface)
public:
JpPlugin();
virtual ~JpPlugin();
virtual QString language() const;
virtual QWidget* ui() const;
};
#endif // JP_PLUGIN_H
Когда я пытаюсь построить это, я получаю ошибку от moc в строке Q_INTERFACES, указывающей интерфейсы, которые должен реализовывать мой плагин:
3> —— Началась сборка: Проект: jp_plugin, Конфигурация: Отладка Win32 ——
3> Moc’ing jp_plugin.h …
3> F: \ moje \ src \ cpp \ winona \ build \ jp_plugin \ jp_plugin.h (15): ошибка: неопределенный интерфейс
========== Построение: 2 успешно завершено, 1 не удалось, 2 обновлено, 0 пропущено ===========
Похоже, moc’ing происходит до того, как файл dict_plugin.h включен, потому что, когда я ввожу опечатку в имя включаемого файла, он не жалуется, что файл не существует, просто завершает сборку с тем же сообщением об ошибке о том, что интерфейс не определен.
Что я делаю неправильно? Благодарю.
Причиной сбоя moc было то, что объявление интерфейса было недоступно. Сбой директивы #include, поскольку файл не найден. Очевидно, moc может обрабатывать директивы #include самостоятельно, но не (по умолчанию?) Не печатает сообщение об ошибке или не останавливает обработку, если файл, который нужно включить, не может быть найден.
Причина, по которой файл заголовка с объявлением интерфейса не может быть найден, заключается в том, что пользовательские параметры сборки, вызывающие запуск moc и генерируемые надстройкой Qt VS, не наследуют путь включения проекта. Мне удалось добавить требуемый путь вручную в командную строку moc, введя страницы свойств файла заголовка плагина, перейдя к Custom Build Tool-> General-> Command Line и добавив дополнительную опцию «-I …» в поле конец. После этого moc обработал заголовок, и сборка прошла успешно.
Других решений пока нет …