65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (3投票s)

2011 年 10 月 20 日

Ms-PL

2分钟阅读

viewsIcon

32578

downloadIcon

425

如何为 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 方法。服务器会向客户端触发 AdditionStartedAdditionCompleted 方法,以适当地通知它。然后客户端执行与这些事件相关的适当操作。

ATLConnectionPointServer.idl 应该将方法 AdditionStartedAdditionCompleted 添加到 _IAddEvents 接口,如图所示

1.png

在服务器上实现 Add 方法,并触发从服务器触发事件的点。

2.png

现在只需编译解决方案,您的服务器就准备好了。

C++/CLI 客户端

创建一个新的项目 Visual C++ => CLR => CLR 控制台应用程序。

3.png

导入服务器 DLL 到托管代码,以使用 Microsoft® .NET Framework 类型库到程序集转换器工具 tlbimp.exe 获得 ATLConnectionPointServerLib.dll,运行以下命令

tlbimp ATLConnectionPointServer.dll 

在您的托管项目中引用生成的程序集,如图所示

4.png

为客户端提供 sink 接口的实现,例如这里所示

5.png

您必须将 sink 注册到服务器,以便服务器可以在触发事件时调用 sink。使用托管客户端,您可以将各个方法作为委托与服务器注册。为此,您可以创建一个 sink 对象实例

创建服务器对象实例,并像这样分别添加 AdditionStartedAdditionCompleted 事件处理程序

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++ 项目。您应该看到以下输出

6.png

历史

  • 2011 年 11 月 15 日:更正了图像链接。
  • 2011 年 10 月 20 日:初始发布。
© . All rights reserved.