[英]DLL-based application framework with bi-directional interfaces (Windows)
this
wasn't the problem, since it's being implicitly cast to IFramework
anyway. this
不是问题,因为它无论如何都被隐式地转换为IFramework
。
I was concerned it may have to do with my methods not returning HRESULT
, or with my stubby implementations of IUnknown::QueryInterface
, but the real problem was merely a compiler setting that had overridden several macros I needed for common calling conventions (perhaps I should have included them in the question). 我担心它可能与我的方法没有返回HRESULT
,或者我的IUnknown::QueryInterface
粗短实现,但真正的问题只是一个编译器设置已经覆盖了我需要的常见调用约定的几个宏(也许我应该将它们包含在问题中)。 This had corrupted the stack. 这破坏了堆栈。
It's interesting though, that it worked will all compilers I tested, even without implementing IUnknown at all - a little research suggests that all serious Windows compilers handle abstract C++ interfaces the same way - namely as a virtual table specifically to be used as a COM interface. 有趣的是,即使没有实现IUnknown,它对我测试的所有编译器都有效 - 一点研究表明所有严肃的Windows编译器都以相同的方式处理抽象C ++接口 - 即作为专门用作COM接口的虚拟表。
Hi. 你好。 I'm trying to create an extensible application framework. 我正在尝试创建一个可扩展的应用程序框架。 My basic concept is this: 我的基本概念是这样的:
The "Framework" box will build an .exe whereas the multiple "Plugin" boxes will build .dll files. “框架”框将构建.exe,而多个“插件”框将构建.dll文件。
However, my implementation is apparently flawed. 但是,我的实施显然存在缺陷。 I have an idea what's the problem, but I'm running out of workarounds. 我知道问题是什么,但我的解决方法已经不多了。 I've done it exactly like this with .NET projects, but the problem I have now didn't apply to the C# environment. 我用.NET项目完成了这个,但我现在遇到的问题并不适用于C#环境。
Consider these interfaces: 考虑这些接口:
class IFramework
{
public:
virtual void FrameworkMethod() = 0;
};
class IPlugin
{
public:
virtual void PluginMethod() = 0;
virtual void PluginCallbackTest() = 0;
virtual void SetFramework(IFramework *framework) = 0;
};
Implementation of the framework: 框架的实施:
class CFramework : IFramework
{
public:
void FrameworkMethod(); // printf("FrameworkMethod");
void DoSomething(); // this is the testbench basically, see below
};
And the implementation of the plugin: 并且插件的实现:
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;
Now to demonstrate that this concept doesn't work: 现在来证明这个概念不起作用:
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
plugin->SetFramework(this); // <-- that is the problem
plugin->PluginCallbackTest(); // <-- runtime crash if compiler differs
FreeLibrary(PluginHandle);
}
The problem is that the SetFramework(this)
doesn't work like COM. 问题是SetFramework(this)
不像COM那样工作。 It's not that it just feels wrong to write it like this - I can't implement a working plugin with a compiler that differs from the one I used to build CFramework (runtime crashes). 这并不是说这样写错了 - 我无法使用与我用于构建CFramework(运行时崩溃)的编译器不同的编译器来实现。
If you want to allow different compilers for the plug-ins from what you use for the app then you need to use COM exclusively across the boundary between app and plug-ins. 如果您希望允许插件使用不同的编译器,那么您需要在应用程序和插件之间的边界上独占使用COM。 That is precisely the problem that COM was designed to solve. 这正是COM旨在解决的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.