Click here to Skip to main content
15,891,033 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello guys!
Is there a way to handle a native C++ event in C++/CLI? How should I make the hook?
I searched almost all day on the internet but haven't found the answer. I hope you have any idea.
C++
class Native{
public:
	__event void myEvent(int i);
	void fireEvent(){
		__raise myEvent(1598);
	};
};

public ref class Managed{
	Native* nativeObject;
public:
	void fireEventHandler(int i){
                printf("Event handled!\n");
        };

	Managed(){
		nativeObject=new Native();
		__hook(&Native::myEvent, nativeObject, &Managed::fireEventHandler );
	};
};

If I try to compile this, I get an error:
error C3731: incompatible event 'void Native::myEvent(int)' and handler 'void Managed::fireEventHandler(int)'; event source and event handler must have the same event type.
1>          The event type of 'Native' is 'native'.
1>          The event type of 'Managed' is 'managed'.

In my application, the native class is compiled in separate DLL without a \clr option, so I cannot hold a reference to managed object.

Thank you in forward!
Posted

 
Share this answer
 
Thank you Lakamraju, actually I've found the solution myself yesterday evening, but this article helped me also, because I didn't think about garbage collector relocation.
My solution is here:
C++
// EventTesting.cpp : main project file.

#include "stdafx.h"
#include "stdio.h"

using namespace System;
using namespace System::Runtime::InteropServices;

class Native{
public:
	void (*myEvent)(int i); // function pointer declaration 
	Native(){
		myEvent=NULL;
	}
	void fireEvent(int i){
		if(myEvent!=NULL) myEvent(i);// calling function thru pointer
	};
	void setmyEventHandler(void (*func)(int i)){
		myEvent = func;// Initializing the function pointer with the incoming one
	}

};

private delegate void myEventDelegate(int i);

public ref class Managed{
	Native* nativeObject;
	myEventDelegate ^ del;
	GCHandle delH;
public:
	void fireEventHandler(int i){
		printf("EVENT FIRED %d\n",i);
	};

	Managed(){
		nativeObject=new Native();
		del = gcnew myEventDelegate(this, &Managed::fireEventHandler);
		delH = GCHandle::Alloc(del);
		System::IntPtr d1 = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(del);
		nativeObject->setmyEventHandler(( void(*)(int))d1.ToPointer());// Calling unmanged library function to initialize function pointer 
	};
	~Managed(){	//Cleanup
		nativeObject->setmyEventHandler(NULL);
		delete nativeObject;
		delH.Free();
	}
	void testEvent(){
		nativeObject->fireEvent(1598);
	}
};


int main(array<system::string xmlns:system="#unknown"> ^args)
{
    Managed^ managedClass = gcnew Managed;
    GC::Collect();
    managedClass->testEvent();
    return 0;
}</system::string>


The only problem with this solution is that we can "register" only one "event handler"... actually this is not an event, just a callback.
Thank you once again!
 
Share this answer
 
v2
Comments
Member 10732575 8-Apr-14 4:19am    
This code works for win 64 bit but does not work for win 32 bit. So is there any way to make it work for win 32 bit??
thank you
peto2242 9-Apr-14 4:05am    
I use it already on 32 bit. The problem is not the platform.
"Does not work" tells us nothing about the problem.
Warren McNeil 9-Oct-17 17:24pm    
Just what is was looking for. Thanks

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