2012-01-31 27 views
8

Tôi đang làm việc trên một ứng dụng đang nhúng Mono và tôi muốn tăng sự kiện từ lớp C++ vào lớp C#. Dưới đây là những gì tôi có:Nhúng Mono: Làm thế nào để bạn nâng cao một sự kiện trong 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); 
} 

Tuy nhiên, raiseMethod luôn trở lại như NULL. Nhìn vào cấu trúc của MonoEvent, có vẻ như các phương thức thêm và xóa đã được phổ biến, nhưng không phải là tăng? Có điều gì đặc biệt tôi phải làm để làm việc này không?

EDIT: Nếu nó quan trọng, đây là hình thức (cơ bản) của đại biểu, lớp và sự kiện tôi đang sử dụng trong lớp C#.

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

Trả lời

5

Có thể xác định sự kiện trong lớp cha mẹ không? Nếu vậy bạn cần phải đi qua lên hệ thống phân cấp lớp với một cái gì đó như sau:

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 sau khi bình luận và đọc lại câu hỏi:

Nó là bình thường rằng phương pháp tăng cho sự kiện này là NULL.

Phương thức này thường trả về giá trị rỗng cho các sự kiện được khai báo bằng từ khóa sự kiện C# hoặc từ khóa sự kiện Visual Basic. Điều này là do các trình biên dịch C# và Visual Basic không tạo ra một phương thức như vậy theo mặc định.

(source)

tôi sợ nó có thể là khó khăn để bắn một sự kiện của một lớp. Bởi vì nó thực sự phá vỡ khái niệm các sự kiện trong .NET - mà nói rằng chính lớp đó chỉ có thể kích hoạt Sự kiện riêng của nó. Trên thực tế, ngay cả từ C# nó là khó khăn để nâng cao sự kiện của lớp khác.

Khái niệm, các sự kiện là cặp phương thức add_handler và remove_handler nơi bạn chỉ định các đại biểu được gọi khi các trường hợp của sự kiện xảy ra. Đó là vào lớp làm thế nào nó thực hiện các sự kiện. Về mặt kỹ thuật, nó chỉ là một trường đại biểu riêng, AFAIK. Bạn có thể thử định vị nó.

Tôi không chắc đó có phải là phương pháp thích hợp hay không, nhưng một trong các câu trả lời trong How do I raise an event via reflection in .NET/C#? mô tả cách tăng sự kiện bằng cách sử dụng sự phản chiếu. Bạn có thể cố gắng chuyển đổi nó thành các cuộc gọi mono_class/mono_field, v.v.

+0

Nope. Thông qua gỡ lỗi tôi đã xác minh tôi đang nhận được sự kiện trở lại chính xác. Chỉ mono_event_get_raise_method trả về null. get_add_method và get_remove_method giá trị trả lại. – Jeff

+0

@Jeff đã cập nhật câu trả lời của tôi – Krizz

3

Câu trả lời của Krizz là hoàn chỉnh nhất. Đây là cách tôi sửa mã của tôi để làm việc như thế nào tôi sẽ "mong đợi".

Tôi đã thay đổi # bên C đến:

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

Sau đó nắm lấy phương pháp mono với

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

Bah, đánh tôi với nó. Đây là khá nhiều quy ước trong .NET anyway. Các tài liệu về các sự kiện sử dụng nó ([Raising một sự kiện] (http://msdn.microsoft.com/en-us/library/wkzf914z.aspx) và liên quan [Làm thế nào để] (http://msdn.microsoft.com /en-us/library/9aackb16.aspx)), và nó được sử dụng khắp nơi trong các lớp khung công tác.Nhỏ sang một bên: các quy ước đặt tên sẽ làm cho 'Entering' và' Exiting' là "đúng" tên cho các trường sự kiện, và 'OnEntering()'/'OnExiting' nên được sử dụng cho các phương thức nâng cao chúng. – millimoose

Các vấn đề liên quan