Основанная на DLL прикладная среда с двунаправленными интерфейсами (Windows) - PullRequest
0 голосов
/ 27 марта 2011

Решено

this не было проблемой, поскольку оно все равно неявно приводилось к IFramework.

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

Интересно, что он сработает со всеми протестированными мной компиляторами, даже без реализации IUnknown - небольшое исследование показывает, что все серьезные компиляторы Windows обрабатывают абстрактные интерфейсы C ++ одинаково, а именнокак виртуальная таблица специально для использования в качестве интерфейса COM.


Привет.Я пытаюсь создать расширяемую структуру приложения.Моя основная концепция такова:

Framework Schematics

В поле «Framework» будет создан файл .exe, тогда как в нескольких полях «Плагин» будут созданы файлы .dll.

Однако моя реализация, по-видимому, имеет недостатки.У меня есть идея, в чем проблема, но у меня заканчиваются обходные пути.Я сделал это точно так же с проектами .NET, но проблема, с которой я столкнулся, теперь не относится к среде C #.

Рассмотрим следующие интерфейсы:

class IFramework
{
public:
    virtual void FrameworkMethod() = 0;
};

class IPlugin
{
public:
    virtual void PluginMethod() = 0;
    virtual void PluginCallbackTest() = 0;
    virtual void SetFramework(IFramework *framework) = 0;
};

Реализацияframework:

class CFramework : IFramework
{
public:
    void FrameworkMethod(); // printf("FrameworkMethod");
    void DoSomething(); // this is the testbench basically, see below
};

И реализация плагина:

class CPlugin : public IPlugin
{
    IFramework *Framework;
public:
    void PluginMethod(); // printf("PluginMethod");
    void PluginCallbackTest(); // Framework->FrameworkMethod();
    void SetFramework(IFramework *framework); // Framework = framework;
};
// plugin factory -> COM interface
extern "C" PLUGIN_API IPlugin *GetPlugin(); // return new CPlugin;

Теперь, чтобы продемонстрировать, что эта концепция не работает:

void CFramework::DoSomething()
{
    HMODULE PluginHandle = LoadLibrary(...); // explicit linking
    auto GetPlugin = ((IPlugin *)(*)())GetProcAddress(...);
    IPlugin *plugin = GetPlugin();
    plugin->PluginMethod();
    // up until here everything's perfectly COM-compliant and works super
    <b>plugin->SetFramework(this); // <-- that is the problem </b>
    plugin->PluginCallbackTest(); // <-- runtime crash if compiler differs
    FreeLibrary(PluginHandle);
}

Проблема в том,что SetFramework(this) не работает как COM.Дело не в том, что просто писать его так неправильно - я не могу реализовать работающий плагин с компилятором, который отличается от того, который я использовал для сборки CFramework (сбой во время выполнения).

1 Ответ

2 голосов
/ 27 марта 2011

Если вы хотите разрешить другим компиляторам для плагинов отличаться от того, что вы используете для приложения, вам нужно использовать COM исключительно через границу между приложением и плагинами.Это именно та проблема, которую COM должен был решить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...