C# – connecting managed event source to an unmanaged event sink

ccomeventsinteropnet

I'm trying to write a managed library in C# that will act as an event source for an existing C++ event sink. The problem I'm having is that when the unmanaged app calls AtlAdvise to get the connection point map for my library it is getting the error "0x80040200" (CONNECT_E_NOCONNECTION) – There are a couple of MSDN articles about that error that are related to unmanaged <–> unmanaged communication and an invalid connection point map in the COM server, but nothing about a managed COM server.

I've loaded up the idl from an unmanaged C++ server that works and got a list of the events that are exposed and then created those same events in my code by doing the following:

Created dll that contains the interfaces I have to implement

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid("xxxxxx")]
public interface IMyInterface 
{
    ...
    methods here
    ...

Created dll that has the class that implements the 3 required interfaces

[Guid("xxxxxxx2")]
[ComSourceInterfaces(typeof(IMyInterface), typeof(IMyOtherInterface), typeof(IMyThirdInterface))]
public class DeviceTranslator : IDisposable, IMyInterface, IMyOtherInterface, IMyThirdInterface
{

created delegates in the namespace of the managed interface

namespace myNS.Interfaces
{
    public delegate void DistributeMessage([In] ref OLDMESSAGE Message);

and created events in the actual IMyInterface

event DistributeMessage myDistributeMessage;

in my class I implemented the event:
public event DistributeMessage myDistributeMessage;

I can place a breakpoint in my constructor, see that the dll gets loaded properly, but when this piece of unmanaged code is called I get the error referenced above: (pDistributeSink is a CEventSink cast to an IUnknown*, and The GUID for IID_IDistributeEvent is the same GUID as IMyInterface)

hr = AtlAdvise(m_pUnknown, pDistributeSink, IID_IDistributeEvent, &m_dwConnectionPointCookie);

At this point I'm totally scratching my head and don't understand what else AtlAdvise needs to get its connection point map back from the CLR…

Best Answer

So I waited 5 days, spinning my wheels every day while unable to figure this out before throwing it up here, and now an hour later I figured it out...go figure.

Here's what I had to do (many thanks to codeproject)

I was inheriting from the outgoing event interface (IMyInterface) AND defining it within my ClassInterface attribute. I also had created the delegates within the namespace IMyInterface is in, not the namespace the DeviceTranslator class is in.

It turns out that I needed to:

  • ONLY define this in the ClassInterface attribute and then not override the methods in that interface.

  • Create delegates within my class library namespace that match the method signatures of IMyInterface exactly (which match the COM event sink client methods)

  • create events within the class DeviceTranslator that are named exactly the same as the IMyInterface methods

It is explained very well in the link i posted above and was the first place that got it to truly sink in how everything is really operating and what has to be created where.