QtPlugins, реализующие несколько интерфейсов и приведение к общему интерфейсу - PullRequest
0 голосов
/ 23 февраля 2012

У меня есть набор интерфейсов, которые могут быть реализованы с помощью плагинов в Qt приложение. Каждый плагин должен реализовывать хотя бы один общий интерфейс, называемый Base_plugin, чтобы обеспечить некоторые основы (описание, имя и т. д.). При вызове определенного интерфейса плагина мне часто приходится получить это основное, чтобы представить его в пользовательском интерфейсе. Это приводит к много кода, как:

Foo_plugin* p = getSuitableFooPlugin();
// cannot use qobject_cast, plug-in interfaces don't derive QObjects
Base_plugin* b = dynamic_cast<Foo_plugin*>(p);
setName(b->name());
p->getAction();

Это работает по крайней мере на GCC, но я боюсь, что это не собирается работа на винде. В качестве альтернативы я мог бы использовать reinterpret_cast или хранить указатели правильного типа на каждый плагин при загрузке их (у меня есть действительный QObject* там). Ни одно из этих решений не кажется действительно чисто для меня.

Есть ли лучший способ обойти эту проблему?

Ответы [ 2 ]

1 голос
/ 23 февраля 2012

Как я понимаю, у вас есть что-то подобное (если вы этого не сделаете, подумайте о рефакторинге, чтобы сделать это так)

struct IBase
{
    virtual QString name() const = 0;
    virtual void setName(const QString name&) = 0;
};
Q_DECLARE_INTERFACE(IBase, "best.app.ever.plugins.base");

struct IFoo
{
    virtual void foo() = 0;
};
Q_DECALRE_INTERFACE(IFoo, "best.app.ever.plugins.foo" );

struct Plugin: QObject, IBase, IFoo
{
    Q_OBJECT()
    Q_INTERFACES(IBase)
    Q_INTERFACES(IFoo);

    //....
};

Q_EXPORT_PLUGIN2(best_app_ever, Plugin);

теперь, когда вы загружаете плагин, вы получаете QObject, и вы shoud используете qobject_cast для приведения этого QObject к вашим интерфейсным классам.

Специализации qobject_cast, которые обрабатывают приведение к вашим интерфейсам, автоматически создаются макросами Q_DECLARE_INTERFACE.

0 голосов
/ 23 февраля 2012

Возможно, я не правильно понимаю, но вы не можете просто написать:

Foo_plugin* p = getSuitableFooPlugin();
setName(p->name());
p->getAction();

Поскольку Foo_plugin наследуется от Base_plugin, а если Base_plugin::name() общедоступно, вы можете позвонитьэто без литья.

...