2012-01-31 10 views
8

私はMonoを埋め込んでいるアプリケーションで作業していますが、C++レイヤーからC#レイヤーにイベントを発生させたいと思います。ここに私が持っているもの:Embedded Mono: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); 
} 

ただし、raiseMethodは常にNULLに戻ります。 MonoEventの構造を見ると、addメソッドとremoveメソッドが実装されたように見えますが、raiseは表示されません。これを機能させるために何か特別なことがありますか?

EDIT:重要なのは、C#レイヤーで使用しているデリゲート、クラス、イベントの(基本的な)フォームです。

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

答えて

5

イベントを親クラスで定義してもよいですか?その場合は次のようなもので、クラス階層を横断する必要があります。コメントや再読み込み質問後

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:

イベントのRaiseメソッドがNULLであることを正常です。

このメソッドは、通常、C#イベントキーワードまたはVisual Basic Eventキーワードで宣言されたイベントに対してnullを返します。これは、C#およびVisual Basicコンパイラがデフォルトでこのようなメソッドを生成しないためです。

source

私はクラスのイベントを発生するのは難しいかもしれ怖いです。それは実際には.NETのイベントの概念を破っているからです。クラス自体がイベントを発生させるだけだと言います。実際には、C#からでも他のクラスのイベントを起こすのは難しいです。

イベントは、イベントの状況が発生したときに呼び出される代理人を指定する、add_handlerメソッドとremove_handlerメソッドのペアです。イベントをどのように実装するかは、クラスに依存します。技術的には、AFAIKという専用の代理フィールドです。 あなたはそれを見つけようとするかもしれません。

適切なアプローチであるかどうかはわかりませんが、回答の1つはHow do I raise an event via reflection in .NET/C#?で、反射を使用してイベントを発生させる方法が説明されています。 mono_class/mono_field呼び出しなどに変換しようとする可能性があります。

+0

いいえでモノ方法をつかん。デバッグを通して、私はイベントを正しく戻していることを確認しました。単なるmono_event_get_raise_methodはnullを返します。 get_add_methodおよびget_remove_methodは値を返します。 – Jeff

+0

@Jeffは私の答えを – Krizz

3

Krizzの回答は最も完全です。これは、私が "期待する"方法で作業するようにコードを修正した方法です。

私の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); 
+0

に更新しました。とにかくこれは.NETの大部分の規約です。イベントに関するドキュメント([Raising an Event](http://msdn.microsoft.com/en-us/library/wkzf914z.aspx))と関連する[How To](http://msdn.microsoft.com /en-us/library/9aackb16.aspx))、それはフレームワーククラスのどこでも使用されています。マイナーなところでは、命名規則は、イベントフィールドの「正しい」名前を「入力」および「終了」にし、それらを呼び出すメソッドには「OnEntering()/ OnExiting」を使用する必要があります。 – millimoose

関連する問題