gpt4 book ai didi

c++ - 聚合对象是否强制成为 IUnknown 引用?

转载 作者:行者123 更新时间:2023-11-30 03:34:58 27 4
gpt4 key购买 nike

我正在尝试使用带有 ATL 的 COM 聚合来实现共享逻辑。我定义了一个基类,称为CameraBase ,这只能通过聚合获得。为此,我添加了 aggregateable注释为 coclass -声明。

[
uuid(...),
aggregatable
]
coclass CameraBase
{
[default] interface ICamera;
};

我还添加了 DECLARE_ONLY_AGGREGATEABLE类定义的宏。

class ATL_NO_VTABLE CCameraBase :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CCameraBase, &CLSID_CameraBase>,
public ISupportErrorInfo,
public IProvideClassInfoImpl<...>,
public IDispatchImpl<...>
{
public:
CCameraBase()
{
}

DECLARE_REGISTRY_RESOURCEID(IDR_CAMERABASE)

DECLARE_ONLY_AGGREGATABLE(CCameraBase)

BEGIN_COM_MAP(CCameraBase)
...
END_COM_MAP()

DECLARE_PROTECT_FINAL_CONSTRUCT()

...
}

现在我有不同的类使用 CameraBase 的逻辑某处。因此,我扩展了父类的 com 映射(例如 SampleCamera ):

BEGIN_COM_MAP(CSampleCamera)
COM_INTERFACE_ENTRY_AGGREGATE(IID_ICamera, m_base)
...
END_COM_MAP

DECLARE_GET_CONTROLLING_UNKNOWN()

因为我希望能够通过 CameraBase 调用成员(通过ICamera接口(interface))从父类,我不想使用COM_INTERFACE_ENTRY_AUTOAGGREGATE , 它将内部对象的指针存储为 IUnknown 的引用.因此,我自己从 FinalConstruct 创建它-方法:

HRESULT FinalConstruct()
{
HRESULT hr;

if (FAILED(hr = m_camera.CoCreateInstance(CLSID_CameraBase, this->GetControllingUnknown(), CLSCTX_INPROC_SERVER)))
return hr;
}

在哪里m_camera定义为 CComPtr<ICamera> .但是,这确实会导致错误 CLASS_E_NOAGGREGATION (结果 0x80040110)。我当前的解决方法是存储两个引用,IUnknownICamera , 查询后面的那个。

if (FAILED(hr = m_base.CoCreateInstance(CLSID_CameraBase, this->GetControllingUnknown(), CLSCTX_INPROC_SERVER)) ||
FAILED(hr = m_base->QueryInterface(&m_camera)))
return hr;

这行得通,但感觉有点奇怪,因为 get 实例化的类 ( CameraBase ) 在两种情况下都是相同的。我错过了什么吗?我是否使用正确的方式聚合内部对象?为什么CoCreateInstance的返回指针必须是 IUnknown 类型, 如果传递了一个外部未知数?

提前致谢! :)

最佳答案

可聚合的 COM 对象提供了两种不同的 IUnknown 实现 - 非委托(delegate)和委托(delegate)。

非委托(delegate)实现是“正常”实现 - 它的 QueryInterface 分发由可聚合对象实现的接口(interface),以及它的 AddRefRelease 控制该对象的生命周期。

顾名思义,委托(delegate)实现将所有三个方法调用委托(delegate)给外部对象的控制 IUnknown。该对象实现的所有其他接口(interface)都具有由该委托(delegate)实现支持的三个 IUnknown 方法。这就是聚合如何为客户端保持它正在处理单个 COM 对象的错觉 - 它允许客户端从外部实现的接口(interface)查询到内部实现的接口(interface),并且(更有趣的是)反之亦然。回想一下,IUnknown 要求 QueryInterface 实现是对称的和可传递的。

当使用非 NULL 控制未知参数调用 CoCreateInstance 时,它必须从内部对象请求 IUnknown - 这是外部获得非 NULL 的唯一机会-委托(delegate)实现。您不能在外部接口(interface)映射中使用来自内部的任何其他接口(interface)指针 - 同样,所有其他接口(interface)都由委托(delegate)未知支持,因此将 QueryInterface 调用转发给它们最终会调用 QueryInterface 在外面,并最终回到接口(interface)映射中,导致无限递归。

关于c++ - 聚合对象是否强制成为 IUnknown 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41614439/

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