Embedded Mono: How do you create an event in C ++?

I am working on an application that embeds Mono, and I would like to raise the event from the C ++ layer to the C # level. Here is what I have:

void* itr(NULL); MonoEvent* monoEvent; while(monoEvent= mono_class_get_events(klass, &itr)) { if(0 == strcmp(eventName, mono_event_get_name(monoEvent))) raiseMethod = mono_event_get_raise_method(monoEvent); } 

However, the raiseMethod method always returns as NULL. If you look at the MonoEvent structure, it looks like add and remove methods have been added, but not a raise? Is there anything special I have to do to get this to work?

EDIT: If that matters, here is the (basic) form of the delegate, class, and events that I use at the C # level.

 public delegate void MyHandler(uint id); public class SimpleComponent : NativeComponent { public event MyHandler OnEnter; public event MyHandler OnExit; } 
+8
c ++ c # events mono
source share
2 answers

Is it possible to define an event in the parent class? If so, you need to go through the class hierarchy with the following:

 MonoEvent* monoEvent; while (klass) { void* itr = NULL; while(monoEvent= mono_class_get_events(klass, &itr)) { if(0 == strcmp(eventName, mono_event_get_name(monoEvent))) raiseMethod = mono_event_get_raise_method(monoEvent); } klass = mono_class_get_parent(klass); } 

EDIT after comment and read again :

It is normal that the raise method for an event is NULL.

This method usually returns null for events declared using the C # event keyword or the Visual Basic Event keyword. This is because the C # and Visual Basic compilers do not generate such a method by default.

( source )

I'm afraid it might be difficult to fire a class event. Because it actually violates the concept of events in .NET - which states that the class itself can only fire its own event. Actually, even with C # it is difficult to raise an event of another class.

Conceptually, events are a pair of add_handler and remove_handler methods in which you specify delegates to call when events occur. It depends on the class, how it implements the events. Technically, this is just a private field for delegates, AFAIK. You can try to find it.

I'm not sure if this is the right approach, but one of the answers in How do I raise an event through reflection in .NET / C #? describes how to attract events using reflection. You can try to convert it to mono_class / mono_field calls, etc.

+5
source share

Crisis's answer is the most comprehensive. This is how I fixed my code to work, as I would expect.

I changed the C # side to:

 public delegate void MyHandler(uint aEntityId); public class SimpleComponent: NativeComponent { public event MyHandler OnEnter; public event MyHandler OnExit; protected void CallOnEnter(uint aEntityId) { if (OnEnter != null) OnEnter(aEntityId); } protected void CallOnExit(uint aEntityId) { if (OnExit!= null) OnExit(aEntityId); } } 

Then grabbed the mono method with

 raiseMethod = mono_class_get_method_from_name(klass, "CallOnEnter", 1); 
+3
source share

All Articles