Reputation: 144
I have a .NET library, that needs to be exposed for COM interop, including some asynchronous operations. As such, I need to implement events. Implementing events from C# seems easy as:
[ComVisible(true)]
[Guid("...")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IClass1Event))]
public class Class1: IClass1
{
public delegate Int32 IntIntFunc(Int32 arg);
public event IntIntFunc Event;
public Int32 RaiseEvent(Int32 param)
{...}
}
[ComVisible(true)]
[Guid("...")]
public interface IClass1
{
Int32 RaiseEvent(Int32 param);
}
[ComVisible(true)]
[Guid("...")]
public interface IClass1Event
{
Int32 Event(Int32 param);
}
But I have trouble implementing a C++ event sink.
Various examples I've come across range from plain IConnectionPoint::Advise
to mere "use VB", but I come across every kind of problem trying to implement them (and no, I can not use VB) - either ATL refuses to implement AddRef
for me, or I can not grasp VTables with my mind (I am very basically versed in C frameworks, unfortunately).
I have no information on what framework is preferable, only that client is C++.
So my question is: what'd be the leanest way to expose .NET events to C++, and consequently, what'd be the simplest way to implement a test sink?
P.S.: Do I really need an events interface to be IDispatch?
Upvotes: 0
Views: 1503
Reputation: 179779
C++ vtables are very easy, if you're familiar with COM. Microsoft pretty much defined them to be identical. That's to say, the MSVC++ vtable for class IUnknown
is binary the same as the COM function table of interface IUnknown
.
Now, you seem to stumble on IConnectionPoint::Advise
. That's understandable. It looks like an interface that you must implement, but it isn't. It's an interface implemented by the event source. You use it to tell the source what sink to use.
To see what happens, pass a dummy IUnknown
object to IConnectionPoint::Advise
and put a breakpoint on your IUnknown::QueryInterface
. You'll see the event source query for IClass1Event
, by GUID of course. Now, when you implement that, you can return it from IUnknown::QueryInterface
.
You don't need to implement an IDispatch
interface. .Net can do without; it's the old Visual Basic 6 which needs it. That's because VB6 is weakly typed and needs late binding.
Upvotes: 1