Решено
this
не было проблемой, поскольку оно все равно неявно приводилось к IFramework
.
Я был обеспокоен, что это может быть связано с тем, что мои методы не возвращаются HRESULT
, или с моими короткими реализациями IUnknown::QueryInterface
, но настоящей проблемой была просто настройка компилятора, которая переопределяла несколько макросов, которые мне были нужны для общих соглашений о вызовах (возможно, мне следовало бы включить их в вопрос).Это повредило стек.
Интересно, что он сработает со всеми протестированными мной компиляторами, даже без реализации IUnknown - небольшое исследование показывает, что все серьезные компиляторы Windows обрабатывают абстрактные интерфейсы C ++ одинаково, а именнокак виртуальная таблица специально для использования в качестве интерфейса COM.
Привет.Я пытаюсь создать расширяемую структуру приложения.Моя основная концепция такова:
В поле «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 (сбой во время выполнения).