我发现,当我向现有 COM/IDL 接口(interface)添加新事件时,有时会遇到奇怪的问题,除非将它们添加到接口(interface)的末尾。
例如,假设我有以下界面:
interface IMyEvents
{
HRESULT FooCallback(
[in] long MyParam1,
[in] long MyParam2,
[in] long MyParam3);
HRESULT BarCallback(
[in] long MyParam1,
[in] BSTR MyParam2,
[in] BSTR MyParam3);
};
现在假设我要添加一个新的回调事件 NewCallback
。如果我像这样添加它,那么当通过 COM 触发事件时,我往往不会遇到任何问题:
interface IMyEvents
{
HRESULT FooCallback(
[in] long MyParam1,
[in] long MyParam2,
[in] long MyParam3);
HRESULT BarCallback(
[in] long MyParam1,
[in] BSTR MyParam2,
[in] BSTR MyParam3);
/* New event added to the end */
HRESULT NewCallback(
[in] BSTR MyParam1,
[in] BSTR MyParam2,
[in] BSTR MyParam3);
};
但是如果我像这样添加它,当事件触发时我可能会遇到各种问题(例如缓冲区溢出)。
interface IMyEvents
{
HRESULT FooCallback(
[in] long MyParam1,
[in] long MyParam2,
[in] long MyParam3);
/* New event added to the middle */
HRESULT NewCallback(
[in] BSTR MyParam1,
[in] BSTR MyParam2,
[in] BSTR MyParam3);
HRESULT BarCallback(
[in] long MyParam1,
[in] BSTR MyParam2,
[in] BSTR MyParam3);
};
我猜它与 DLL 入口点、地址偏移或类似的东西有关。或者可能是因为我没有正确地重新构建某些东西,并且将其添加到最后使其能够完全幸运地工作。
谁能解释一下这种行为吗?
最佳答案
您不应该修改现有的 COM 接口(interface)。未随更改一起编译的客户端不会意识到这一点,并将像更改前一样继续调用。
结果是,现有客户端使用长整数调用 BarCallback,但得到的 NewCallback 认为该长整数是 BSTR。结果往往令人不快。
最后添加新功能时您会遇到类似的问题。较旧的 COM 对象没有实现新函数,当您尝试调用它时可能会崩溃。
但是,如果您没有使用旧接口(interface)的现有客户端,只需确保取消注册所有内容并替换您生成的对象、客户端和代理以及 stub 即可。
关于c++ - 为什么需要将新事件添加到 IDL 接口(interface)的*末尾*?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/856321/