现有的普通C++类能否在不变成 COM 类的情况下实现 IDL 接口
Can an existing plain C++ class implement IDL interface without turning into a COM class?
我有一个COM对象CProvider,使用ATL实现。此类包含另一个类 CProviderInfo,并维护此内部类类型的对象的静态向量。
下面是它的外观:
//-------------
// 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上引入一个返回静态向量m_vProviderInfo副本的方法。为了尝试按照COM规则进行游戏,我为此目的引入了一个新的IDL接口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有效地将静态向量m_vProviderInfo的内容复制到IProviderInfoRetriever::GetProviderInfo((的输出SAFEARRAY中。
我的问题是:是否有可能让内部类CProviderInfo实现IProviderInfo?这会破坏创建CProviderInfo类型的局部变量的现有代码吗?
我做了一些广泛的研究,答案很简单:是的,但这并不容易。您极不可能只让普通的 C++ 类继承/实现 IDL 中定义的接口,而不会破坏依赖于所述C++类的现有代码。
首先,如果您使用 ATL 的功能将C++类转换为 COM 类,您会突然发现由于 ATL 宏引入的所有纯虚函数,这个C++类已经变得抽象。所以,至少,你会有IUnknown
的AddRef()
,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 个选择:
使用 ATL 的工具将C++类转换为 COM 类。
这会将您的C++类变成抽象类。您必须修改源代码中的所有位置,以创建C++类的对象以改用ATL的类,即
CComObject
,CComObjectStack
...等。直接和手动继承/实现 IDL 中定义的接口。
这将需要根据您的接口提供您自己的
IUnknown
、IDispatch
或两者的实现,以及接口本身定义的任何方法的实现。此选项的优点是不太可能破坏代码库中C++类的任何现有用法。但是,在没有 ATL 的情况下滚动自己的 COM 接口实现并不总是那么容易,尤其是当您的 C++ 类涉及复杂方案(例如互操作(时。
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- C#COM组装实现C 接口
- 如何实现C#使用本机C 的com的接口
- COM - 避免重复实现 IUnknown
- 现有的普通C++类能否在不变成 COM 类的情况下实现 IDL 接口
- 用visual c++实现COM对象的声明/定义和实例化
- . net实现的c++接口,暴露于COM
- 在非托管c++程序中实现一个c# DLL COM文件
- 代理dll:方法覆盖/方法转发(COM实现继承)
- 在c++中实现COM接口,方法不公开
- visual实现COM接口c++ / vc++ 6.0 / MFC
- 如何定义COM组件类的实现
- 每个新的COM类都必须重新实现IUnknown接口
- 如何实现C++COM事件处理的接收器
- 我如何实现发送_Recordset **参数到COM+应用程序
- 用c++ (ATL, MFC或纯c++)处理COM事件,实现Java互操作