gpt4 book ai didi

c++ - C++ COM(ATL)中添加新接口(interface)需要注意什么

转载 作者:行者123 更新时间:2023-11-28 02:14:04 26 4
gpt4 key购买 nike

我添加了一个新接口(interface) IAEx,它是从现有接口(interface) IA(派生自 IDispatch)扩展而来的。

idl 有哪些变化?我已经更改了 coclass 定义以从新定义继承。我更改了 idl 中的 coclass 条目,之前是这样的。

(我需要默认界面作为新界面)

coclass CAx
{

[default] interface IA
[default, source] dispinterface IAEvents;
};

并改为

coclass CAx
{

[default] interface IAEx
[default, source] dispinterface IAEvents;
};

我可以更改默认界面吗?

coclass 定义更改。旧的

class ATL_NO_VTABLE CAx: 
...
public CCIDispatchImpl<IA, &IID_IA, &LIBID_CCALib>,

新的。

class ATL_NO_VTABLE CAx: 
...
public CCIDispatchImpl<IAEx, &IID_IAEx, &LIBID_CCALib>,

这样好吗?

COM MAP条目修改:旧的:

COM_INTERFACE_ENTRY(IA)
COM_INTERFACE_ENTRY2(IDispatch,IA)

新的:

COM_INTERFACE_ENTRY(IAEx)
COM_INTERFACE_ENTRY2(IDispatch,IAEx)

我是否也需要在 COM MAP 中添加旧接口(interface)?

最佳答案

不,这是对客户端程序的彻底改变。要记住的黄金法则 #1 是 names 在 COM 中非常不重要,只有 uuids 重要。规则 #2 是 COM 组件具有机器作用域,修改组件会影响机器上使用该组件的 每个 程序。另一种说法是 COM 存在严重的 DLL hell 问题。

因此,当您在机器上安装您的组件时,首先会发生的事情是每个使用它的程序都将停止工作。他们仍在寻找“IA”接口(interface) uuid,但它已不存在了。它们因 E_NOINTERFACE 而失败。避免这种情况的唯一方法是使用新类型库重新编译客户端程序,并在部署更新的 COM 组件的同时部署它们。这通常很难安排,因为他们没有共同的程序员或公司。通常只有用户可以执行此操作,他们很少知道如何正确执行此操作或知道如何排除故障。

如果您希望您的更新向后兼容,那么您必须向您的组件类添加一个新接口(interface)。它不能是 [default] 接口(interface),因为现有的客户端程序希望将旧接口(interface)作为默认接口(interface)。然而,这会导致一个新问题,使用 IDispatch 的客户端运行时通常只支持一个默认接口(interface)。通常是因为他们没有将接口(interface)作为主要语言结构的概念。换句话说,您的客户端程序员无法调用 IUnknown::QueryInterface(),因此根本无法使用您的新接口(interface)。所以不是通用的解决方案。

在 COM 中违反接口(interface)是不可变的规则在技术上是可能的。您可以将新方法添加到 IDispatch 接口(interface)的末尾。现有的客户端代码不知道它们,因此永远不会调用它们并继续正确运行组件的旧版本和新版本。假设您知道如何在不引起破坏性行为变化的情况下维护遗留方法,通常比看起来更难。但是仍然存在 DLL hell 问题,当客户端代码的更新版本遇到组件的旧版本时,世界就会崩溃。乍一看这似乎不太可能,但在更换机器或重新镜像时,这往往会在很久以后出错。非常丑陋的场景,无法诊断运行时故障,并且最初涉及的任何人都不在身边或不记得细节。

唯一真正安全的方法是创建一个新版本。修改所有 uuid(LIBID、CLSID 和 IID)并更改 DLL 文件名。现在新旧版本可以共存,客户程序员可以随意使用你的新版本。可能仍然存在部署问题,但故障很容易诊断,客户端程序失败并显示“类未注册”。

关于c++ - C++ COM(ATL)中添加新接口(interface)需要注意什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34607353/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com