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...
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.
I believe this is the correct codeproject link: http://www.codeproject.com/KB/COM/cominterop.aspx#NetEvents
User contributions licensed under CC BY-SA 3.0