Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++/CLI

COM connection point callback for a C++/CLI client

4.91/5 (3 votes)
15 Nov 2011Ms-PL2 min read 31.7K   408  
How to implement COM connection point callback for a C++CLI client.

Introduction

If you have to write interop code, should you use C# and P/Invoke, or should you use C++/CLI? The clients for a COM connection point server can be written in C++ and in C# managed code. Recently, I got a query about the possibility of a managed C++/CLI client for a COM connection point server. A search on the web gave many samples of C++ and C# managed code but none for a C++/CLI client. It is a topic of debate; refer to this blog. It says “With C++/CLI, you can use the API natively exactly like it's meant to be used, and then "expose" the code to the managed world via C++/CLI”. This motivated me to write an article on how to implement a COM connection point callback for a C++/CLI client.

COM Server with a Connection Point

To start, I needed a COM server with a connection point. In my scenario, the server exposes a COM method:

C++
HRESULT Add(int nFirst, int nSecond)

The server also defines ConnectionPointContainer and connection points so that clients can register with it. In addition, the server defines an interface, _IAddEvents, which has two methods in it:

C++
HRESULT AdditionCompleted(int nResult)
HRESULT AdditionStarted()

You should have a server interface IAdd that can be called from the client. If you build the server, you will notice that there are two interfaces defined here. One is IAdd, which implements IDispatch, and the other is the dispinterface _IAddEvents. The client provides the implementation for _IAddEvents and invokes the Add method on the server. The server fires the AdditionStarted and AdditionCompleted methods on the client to notify it appropriately. Then the client performs the appropriate actions associated with these events.

ATLConnectionPointServer.idl should add methods AdditionStarted and AdditionCompleted to the _IAddEvents interface, as shown in figure:

1.png

Implement the Add method on the server and the trigger points for firing events from the server.

2.png

Now just compile the solution and your server is ready.

C++/CLI Client

Create a new project Visual C++ => CLR => CLR Console Application.

3.png

Import the server DLL to managed code to obtain ATLConnectionPointServerLib.dll by using the Microsoft® .NET Framework Type Library to Assembly Converter tool, tlbimp.exe, running the following command:

tlbimp ATLConnectionPointServer.dll 

Reference the resulting assembly in your managed project, as shown in the figure below:

4.png

Provide an implementation for the sink interface on the client, such as the one shown here:

5.png

You have to register the sink with the server so the server can invoke the sink when firing the events. With the managed client, you register individual methods as delegates with the server. To accomplish this, you create an instance of the sink object:

Create an instance of the server object and add the AdditionStarted and AdditionCompleted event handlers separately, like this:

C++
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 );

Now just compile the solution and your C++/CLI client is ready.

Run the MC++ project. You should see the following output:

6.png

History

  • 15 Nov 2011: Corrected image links.
  • 20 Oct 2011: Initial release.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)