Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
Hi,

I come from a .net background and I am fairly new to developing in C++. I am building a library which carry's out low level functionality, wrapped by a C# library so it can be used in other projects.

I am well used to events in C# and raising events when something meaningful happens. What I'm not sure about it how to raise "an event" in C++ that is then handled/understood by the C# code and can be bubbled up from there and used when the wrapper is being used.

I have written plenty of pinvoke code where I call functions as I need them from the C++ dll but I'm not sure how to send information from the C++ to the C# in order to raise the event I need in the wrapper.

Thanks for the advice in advance!

Robert
Posted
Comments
KarstenK 4-Dec-14 6:37am    
an C# delegate is similar to a callback function in C++.

I have added callback support to my article Calling all stations which handles now also callbacks from and into C++. Step through the code and see my solutions.
 
Share this answer
 
the easiest approach would be to write a COM object in the DLL - create an ATL simple object with a methods (say) HRESULT Register(IUnknown *eventCallback), HRESULT UnRegister(void)
(don't bother with dual/dispatch, custom is fine, but make it automation safe)

Use tlbimp (on the generated) tlb file to get C# to 'see' it via the interop assembly

Create a com object in the C#, use regasm to create the tlb for the c++ object to #import it

(tlb's are meta for interface description interchange)

in your c# 'master', create one of your C# com objects, create one of the c++ com objects, call register and pass it your c# object

Now the c++ can store that pointer (in a CComQIPtr<yourc#interface> m_remoteEventSink) and call up to it whenever

c++ code
#import "tlbCreatedFromRegAsm.tlb" raw_interfaces_only no_namespace

// ... ATL class definition

HRESULT Register(IUnknown *eventSink)
{
    m_eventSink=eventSink;
    // start CoolFunctionalLoop thread here, maybe
    // ...
    return S_OK;
}

HRESULT Unregister()
{
    // end CoolFunctionalLoop here 
    // ...

    m_eventSink.Release();
}

void CoolFunctionalLoop()
{
    while(1)
    {
        m_eventSink->FireSomethingInteresting()
    }
}

private:

CComQIPtr<c#interface> m_eventSink;


// ATL class ends


This Article[^] covers it almost completely
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900