Embedded Mono: Как вы вызываете событие в C ++? - PullRequest
8 голосов
/ 01 февраля 2012

Я работаю над приложением, которое встраивает Mono, и я хотел бы поднять событие из уровня C ++ в уровень 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);
 }

Тем не менее, метод поднимать всегда возвращается как NULL.Глядя на структуру MonoEvent, похоже, что методы добавления и удаления были заполнены, но не повышение?Есть ли что-то особенное, что я должен сделать, чтобы заставить это работать?

РЕДАКТИРОВАТЬ: Если это имеет значение, вот (базовая) форма делегата, класса и событий, которые я использую в слое C #.

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

Ответы [ 2 ]

5 голосов
/ 01 февраля 2012

Может ли событие быть определено в родительском классе?Если это так, вам нужно пройти по иерархии классов следующим образом:

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

РЕДАКТИРОВАТЬ после комментария и перечитать вопрос :

Это нормально, чтометод повышения для события равен NULL.

Этот метод обычно возвращает ноль для событий, объявленных с ключевым словом события C # или ключевым словом события Visual Basic.Это связано с тем, что компиляторы C # и Visual Basic по умолчанию не генерируют такой метод.

( source )

Боюсь, что это может быть труднозапустить событие класса.Потому что это фактически нарушает концепцию событий в .NET, которая говорит, что сам класс может запускать только свое собственное событие.На самом деле, даже из C # трудно поднять событие другого класса.

Концептуально события - это пара методов add_handler и remove_handler, в которых вы указываете делегатов, которые будут вызываться при возникновении обстоятельств события.Это до класса, как это реализует события.Технически, это просто поле для личных делегатов, AFAIK.Вы можете попытаться найти его.

Я не уверен, что это правильный подход, но один из ответов в Как вызвать событие с помощью отражения в .NET / C #? описывает, как вызвать событие с помощью отражения,Вы можете попытаться преобразовать его в вызовы mono_class / mono_field и т. Д.

4 голосов
/ 01 февраля 2012

Ответ Криза самый полный. Вот как я исправил свой код так, как я ожидал.

Я изменил сторону C # на:

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

Затем схватил моно метод с помощью

raiseMethod = mono_class_get_method_from_name(klass, "CallOnEnter", 1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...