2012-01-31 9 views
8

Estoy trabajando en una aplicación que está incorporando Mono, y me gustaría plantear un evento desde la capa C++ en la capa C#. Esto es lo que tengo:Mono incrustado: ¿cómo se plantea un evento en C++?

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); 
} 

Sin embargo, raiseMethod siempre vuelve como NULL. Al observar la estructura del MonoEvent, parece que se completaron los métodos de agregar y quitar, pero no el aumento. ¿Hay algo especial que deba hacer para que esto funcione?

EDITAR: Si es importante, aquí está la forma (básica) del delegado, la clase y los eventos que estoy usando en la capa C#.

public delegate void MyHandler(uint id); 
public class SimpleComponent : NativeComponent 
{ 
    public event MyHandler OnEnter; 
    public event MyHandler OnExit; 
} 

Respuesta

5

¿Se puede definir el evento en la clase principal? Si lo que necesita para recorrer la jerarquía de clases con algo como lo siguiente:

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); 
} 

Edición después de comentario y releyendo pregunta:

Es normal que el método de aumento para el evento es NULL.

Este método generalmente devuelve nulo para los eventos declarados con la palabra clave de evento C# o la palabra clave del evento de Visual Basic. Esto se debe a que los compiladores C# y Visual Basic no generan dicho método de forma predeterminada.

(source)

me temo que puede ser difícil para disparar un evento de una clase. Porque en realidad está rompiendo el concepto de eventos en .NET, que dice que la clase en sí misma solo puede lanzar su propio evento. En realidad, incluso desde C# es difícil plantear el evento de otra clase.

Conceptualmente, los eventos son un par de métodos add_handler y remove_handler donde especifica los delegados que se llamarán cuando ocurran las circunstancias del evento. Depende de la clase cómo implementa los eventos. Técnicamente, es solo un campo delegado privado, AFAIK. Puede tratar de localizarlo.

No estoy seguro de si es un enfoque adecuado, pero una de las respuestas en How do I raise an event via reflection in .NET/C#? describe cómo generar eventos mediante la reflexión. Puede intentar convertirlo en llamadas mono_class/mono_field, etc.

+0

Nop. Mediante la depuración, verifiqué que estoy recuperando el evento correctamente. Just mono_event_get_raise_method devuelve null. get_add_method y get_remove_method return values. – Jeff

+0

@Jeff actualizó mi respuesta – Krizz

3

La respuesta de Krizz es la más completa. Así es como arreglé mi código para trabajar cómo lo "esperaría".

I cambió el # lado C a:

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); 
    } 
} 

luego agarró el método de mono con

raiseMethod = mono_class_get_method_from_name(klass, "CallOnEnter", 1); 
+0

Bah, pásame. Esto es más o menos la convención en .NET de todos modos. Los documentos sobre eventos lo usan ([Raising an Event] (http://msdn.microsoft.com/en-us/library/wkzf914z.aspx) y el relacionado [How To] (http://msdn.microsoft.com) /en-us/library/9aackb16.aspx)), y también se utiliza en todas las clases de framework.Dejando a un lado a un lado: las convenciones de nomenclatura convertirían 'Ingresar' y 'Salir' en los nombres 'correctos' para los campos de evento, y 'Al ingresar() '/' Al salir 'se debería usar para los métodos que los plantean. – millimoose

Cuestiones relacionadas