简体   繁体   English

嵌入式单声道:如何在C ++中引发事件?

[英]Embedded Mono: How do you raise an event in C++?

I'm working on an application that's embedding Mono, and I'd like to raise an event from the C++ layer into the C# layer. 我正在开发一个嵌入Mono的应用程序,我想将一个事件从C ++层引发到C#层。 Here's 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, raiseMethod always comes back as NULL. 但是,raiseMethod总是以NULL形式返回。 Looking at the structure of the MonoEvent, it looks like the add and remove methods were populated, but not the raise? 看一下MonoEvent的结构,看起来像是添加和删除方法,但不是加注? Is there something special I have to do to get this to work? 为了让它发挥作用,我有什么特别的事要做吗?

EDIT: If it matters, here's the (basic) form of the delegate, class, and events I'm using in the C# layer. 编辑:如果重要,这里是我在C#层使用的委托,类和事件的(基本)形式。

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

May the event be defined in parent class? 可以在父类中定义事件吗? If so you need to traverse up the class hierarchy with something like 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 re-reading question : 评论和重读问题后编辑

It is normal that the raise method for event is NULL. 事件的raise方法为NULL是正常的。

This method usually returns null for events declared with the C# event keyword or the Visual Basic Event keyword. 对于使用C#事件关键字或Visual Basic Event关键字声明的事件,此方法通常返回null。 This is because the C# and Visual Basic compilers do not generate such a method by default. 这是因为默认情况下C#和Visual Basic编译器不生成这样的方法。

( source ) 来源

I am afraid it may be hard to fire an event of a class. 我担心可能很难发动课堂活动。 Because it is actually breaking the concept of events in .NET - which says that the class itself can only fire its own Event. 因为它实际上打破了.NET中事件的概念 - 它说类本身只能触发自己的事件。 Actually, even from C# it is hard to raise the event of other class. 实际上,即使是C#也很难引起其他类的事件。

Conceptually, events are pair of add_handler and remove_handler methods where you specify delegates to be called when event's circumstances occur. 从概念上讲,事件是add_handler和remove_handler方法的对,您可以在其中指定在事件发生时要调用的委托。 It is up to class how it implements events. 它是如何实现事件的。 Technically, it is just a private delegate field, AFAIK. 从技术上讲,它只是一个私人代表领域,AFAIK。 You may try to locate it. 您可以尝试找到它。

I am not sure if it is a proper approach, but one of the answers in How do I raise an event via reflection in .NET/C#? 我不确定它是否是一种正确的方法,但是如何通过.NET / C#中的反射来引发事件? describes how to raise event using reflection. 描述了如何使用反射引发事件。 You might attempt to convert it into mono_class / mono_field calls, etc. 您可能会尝试将其转换为mono_class / mono_field调用等。

Krizz's answer is the most complete. Krizz的答案是最完整的。 This is how I fixed my code to work how I would "expect". 这就是我修复代码以实现“期望”的方式。

I changed the C# side to: 我将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);
    }
}

Then grabbed the mono method with 然后抓住单声道方法

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM