C++/CLI 客户端的 COM 连接点回调






4.91/5 (3投票s)
如何为 C++/CLI 客户端实现 COM 连接点回调。
引言
如果您需要编写互操作代码,应该使用 C# 和 P/Invoke,还是应该使用 C++/CLI?COM 连接点服务器的客户端可以使用 C++ 和 C# 管理代码编写。最近,我收到一个关于 COM 连接点服务器是否可以使用托管 C++/CLI 客户端的询问。在网上搜索,可以找到许多 C++ 和 C# 管理代码的示例,但没有针对 C++/CLI 客户端的示例。这是一个争论的话题;请参阅这篇 博客。其中提到“使用 C++/CLI,您可以像其设计用途一样原生地使用 API,然后通过 C++/CLI 将代码“暴露”给托管世界”。这促使我撰写一篇文章,介绍如何为 C++/CLI 客户端实现 COM 连接点回调。
具有连接点的 COM 服务器
首先,我需要一个具有连接点的 COM 服务器。在我的场景中,服务器暴露了一个 COM 方法
HRESULT Add(int nFirst, int nSecond)
服务器还定义了 ConnectionPointContainer
和连接点,以便客户端可以向其注册。此外,服务器定义了一个接口 _IAddEvents
,其中包含两种方法
HRESULT AdditionCompleted(int nResult)
HRESULT AdditionStarted()
您应该有一个服务器接口 IAdd
,可以从客户端调用。如果您构建服务器,您会注意到这里定义了两个接口。一个是 IAdd
,它实现了 IDispatch
,另一个是 dispinterface _IAddEvents
。客户端提供 _IAddEvents
的实现,并在服务器上调用 Add
方法。服务器会向客户端触发 AdditionStarted
和 AdditionCompleted
方法,以适当地通知它。然后客户端执行与这些事件相关的适当操作。
ATLConnectionPointServer.idl 应该将方法 AdditionStarted
和 AdditionCompleted
添加到 _IAddEvents
接口,如图所示
在服务器上实现 Add
方法,并触发从服务器触发事件的点。
现在只需编译解决方案,您的服务器就准备好了。
C++/CLI 客户端
创建一个新的项目 Visual C++ => CLR => CLR 控制台应用程序。
导入服务器 DLL 到托管代码,以使用 Microsoft® .NET Framework 类型库到程序集转换器工具 tlbimp.exe 获得 ATLConnectionPointServerLib.dll,运行以下命令
tlbimp ATLConnectionPointServer.dll
在您的托管项目中引用生成的程序集,如图所示
为客户端提供 sink 接口的实现,例如这里所示
您必须将 sink 注册到服务器,以便服务器可以在触发事件时调用 sink。使用托管客户端,您可以将各个方法作为委托与服务器注册。为此,您可以创建一个 sink 对象实例
创建服务器对象实例,并像这样分别添加 AdditionStarted
和 AdditionCompleted
事件处理程序
AddClass^ a = gcnew AddClass();
if(a == nullptr) //check to see if a is still nullptr
Console::WriteLine("reference not allocated to handle");
ManagedSink^ ms = gcnew ManagedSink();
if(ms == nullptr) //check to see if a is still nullptr
Console::WriteLine("reference not allocated to handle");
a->AdditionStarted += gcnew _IAddEvents_AdditionStartedEventHandler
(ms, &ManagedSink::AdditionStarted );
a->AdditionCompleted += gcnew _IAddEvents_AdditionCompletedEventHandler
(ms, &ManagedSink::AdditionCompleted );
a->Add(1, 5);
a->AdditionStarted -= gcnew _IAddEvents_AdditionStartedEventHandler
(ms, &ManagedSink::AdditionStarted );;
a->AdditionCompleted -= gcnew _IAddEvents_AdditionCompletedEventHandler
(ms, &ManagedSink::AdditionCompleted );
现在只需编译解决方案,您的 C++/CLI 客户端就准备好了。
运行 MC++ 项目。您应该看到以下输出
历史
- 2011 年 11 月 15 日:更正了图像链接。
- 2011 年 10 月 20 日:初始发布。