Quantcast
Channel: Common Language Runtime Internals and Architecture forum
Viewing all articles
Browse latest Browse all 1710

Managed C++ Unmanaged C++ Events Delegates and Function Pointers

$
0
0

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


Viewing all articles
Browse latest Browse all 1710

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>