gpt4 book ai didi

c++ - 现有的纯 C++ 类是否可以在不转换为 COM 类的情况下实现 IDL 接口(interface)?

转载 作者:行者123 更新时间:2023-11-28 05:51:45 27 4
gpt4 key购买 nike

我有一个使用 ATL 实现的 COM 对象 CProvider。此类包含另一个类 CProviderInfo,并维护此内部类类型的对象的静态 vector 。

这是它的样子:

//-------------
// CProvider.h
//-------------

//
// COM object class
//
class ATL_NO_VTABLE CProvider :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CProvider, &CLSID_Provider>,
public Interface1,
public Interface2
{
public:
BEGIN_COM_MAP(CProvider)
COM_INTERFACE_ENTRY(Interface1)
COM_INTERFACE_ENTRY(Interface2)
END_COM_MAP()

//
// The inner class
//
class CProviderInfo
{
public:
CProviderInfo();
CComBSTR m_strName;
GUID m_guidRegistration;
};

private:
//
// static vector of inner class type
//
static vector<CProviderInfo> m_vProviderInfo;
};

我想做的是在 CProvider 上引入一个方法,该方法返回静态 vector m_vProviderInfo 的拷贝。为了遵循 COM 规则,我为此引入了一个新的 IDL 接口(interface) IProviderInfoRetriever:

//---------
// IDL file
//---------

//
// IProviderInfoRetriever interface
//
[
// uuid, version ... etc.
]
interface IProviderInfoRetriever : IUnknown
{
HRESULT GetProviderInfo(
[out, retval] SAFEARRAY(IProviderInfo*) *ppProviderInfo);
}

//
// The interface of the class holding the info
//
[
// uuid, version ... etc.
]
interface IProviderInfo : IUnknown
{
[propget]
HRESULT Name(
[out, retval] BSTR *pbstrName);

[propget]
HRESULT Registration(
[out, retval] GUID *pguidRegistration);
}

我的计划是让 CProvider 实现 IProviderInfoRetriever 有效地将静态 vector m_vProviderInfo 的内容复制到 IProviderInfoRetriever 的输出 SAFEARRAY 中::GetProviderInfo()

我的问题是:是否可以让内部类 CProviderInfo 实现 IProviderInfo?这会破坏创建 CProviderInfo 类型局部变量的现有代码吗?

最佳答案

我做了一些广泛的研究,答案很简单:是的,但这并不容易。您不太可能只让普通的 C++ 类继承/实现 IDL 中定义的接口(interface),而不破坏依赖于所述 C++ 类的现有代码。

首先,如果您使用 ATL 的工具将您的 C++ 类转换为 COM 类,您会突然发现由于 ATL 宏引入的所有纯虚函数,这个 C++ 类已经变成了抽象类。因此,至少,您将拥有 IUnknownAddRef()Release()QueryInterface() 通过 ATL 宏作为纯虚函数添加到您的 C++ 类中,例如

class ATL_NO_VTABLE CProviderInfo:
public CComObjectRootEx<CComMultiThreadModel>,
public IProviderInfo
{
public:
BEGIN_COM_MAP(CProviderInfo)
COM_INTERFACE_ENTRY(IProviderInfo)
END_COM_MAP() // This line adds IUnknown's AddRef(), Release(),
// and QueryInterface() as pure virtual functions.

// ...
};

仅此一项就会破坏用于创建 C++ 类实例的任何现有代码,无论它们是在堆栈上还是在堆上(使用 new 运算符)。因此,最终您有 2 个选择:

  1. 使用 ATL 的工具将您的 C++ 类转换为 COM 类。

    这会将您的 C++ 类变成抽象类。您必须修改源代码中创建 C++ 类对象的所有位置,以改用 ATL 的类,即 CComObjectCComObjectStack ... 等。

  2. 直接手动继承/实现IDL中定义的接口(interface)。

    这将需要根据您的接口(interface)提供您自己的 IUnknownIDispatch 或两者的实现,以及由您的接口(interface)本身定义的任何方法的实现。此选项的优点是它不太可能破坏代码库中 C++ 类的任何现有使用。

    但是,在没有 ATL 的情况下滚动您自己的 COM 接口(interface)实现并不总是那么容易,尤其是当您的 C++ 类涉及复杂场景时,例如互操作。

关于c++ - 现有的纯 C++ 类是否可以在不转换为 COM 类的情况下实现 IDL 接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35112867/

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