I'm having difficulty subscribing to events from an unmanaged C++ class in a managed C++ class. I'm a C# developer wrestling with Interop and C++ is an alien environment so I'm possibly missing something obvious.
I have to have an unmanaged C++ class because the SDK I'm using only supports this; the managed C++ is a wrapper allowing access from the C# project that I'm writing the rest of the project in.
I can subscribe to events from managed classes and believe that I need a delegate because the unmanaged code needs a pointer it can understand not the address of a managed function. C3374: can't take address of 'function' unless creating delegate instance was very useful in this respect.
But I cannot get the following code to compile or function - the code to subscribe to the events is in ManagedNS2::ManagedTarget::Init() and my attempts are preceeded with the compile error generated.
#include "stdafx.h" #include <iostream> using namespace System; using namespace std; using System::Runtime::InteropServices::Marshal; namespace ManagedNS1 { public ref class ManagedSource { public: delegate void ManagedSourceEventDelegate(); event ManagedSourceEventDelegate^ ManagedSourceEvent; void RaiseEvent(); }; } void ManagedNS1::ManagedSource::RaiseEvent() { ManagedSourceEvent(); } namespace UnManagedNS1 { public class UnManagedSource { public: __event void UnManagedSourceEvent(); void RaiseEvent(); }; } void UnManagedNS1::UnManagedSource::RaiseEvent() { UnManagedSourceEvent(); } namespace ManagedNS2 { public ref class ManagedTarget { public: delegate void MyEventDelegate(); ManagedNS1::ManagedSource managedSource; UnManagedNS1::UnManagedSource* unmanagedSource; MyEventDelegate^ del; ManagedTarget(); ~ManagedTarget(); void EventHandler1(); void EventHandler2(); void Simulate(); void Init(); }; } ManagedNS2::ManagedTarget::ManagedTarget() { unmanagedSource = new UnManagedNS1::UnManagedSource(); } ManagedNS2::ManagedTarget::~ManagedTarget() { delete unmanagedSource; } void ManagedNS2::ManagedTarget::Init() { //subscribe to events from managedSource - this works managedSource.ManagedSourceEvent += gcnew ManagedNS1::ManagedSource::ManagedSourceEventDelegate(this, &ManagedNS2::ManagedTarget::EventHandler1); //subscribe to events from the unmanaged source - without delegate gives incompatible event (because unmanaged code needs native pointer it can understand; not an address of a managed function) //__hook(&UnManagedNS1::UnManagedSource::UnManagedSourceEvent, &unmanagedSource, &ManagedNS2::ManagedTarget::EventHandler); del = gcnew MyEventDelegate(this, &ManagedNS2::ManagedTarget::EventHandler2); IntPtr pMyEventDelegate = Marshal::GetFunctionPointerForDelegate(del); //improper syntax for specifying event handler in __hook/__unhook //__hook(&UnManagedNS1::UnManagedSource::UnManagedSourceEvent, &unmanagedSource, pMyEventDelegate.ToPointer()); //invalid argument for delegate constructor; delegate target needs to be a pointer to a member function //managedSource.ManagedSourceEvent += gcnew ManagedNS1::ManagedSource::ManagedSourceEventDelegate(this, pMyEventDelegate.ToPointer()); //invalid argument for delegate constructor; delegate target needs to be a pointer to a member function //managedSource.ManagedSourceEvent += gcnew ManagedNS1::ManagedSource::ManagedSourceEventDelegate(this, Marshal::GetFunctionPointerForDelegate(del).ToPointer()); } void ManagedNS2::ManagedTarget::EventHandler1() { printf("Event Detected From Managed\n\r"); } void ManagedNS2::ManagedTarget::EventHandler2() { printf("Event Detected From Unmanaged\n\r"); } void ManagedNS2::ManagedTarget::Simulate() { managedSource.RaiseEvent(); unmanagedSource->RaiseEvent(); } int _tmain(int argc, _TCHAR* argv[]) { ManagedNS2::ManagedTarget t; t.Init(); //subscribe to events t.Simulate(); //raise the events char c; std::cout << "Press Return to Exit"; c = cin.get(); return 0; }
Dave Bradshaw