2012-01-31 8 views
8

मैं एक ऐसे अनुप्रयोग पर काम कर रहा हूं जो मोनो एम्बेड कर रहा है, और मैं सी ++ परत से सी # परत में एक ईवेंट को उठाना चाहता हूं। यहां मेरे पास है:एंबेडेड मोनो: आप 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); 
} 

हालांकि, raise विधि हमेशा वापस के रूप में वापस आती है। मोनोइवेंट की संरचना को देखते हुए, ऐसा लगता है कि जोड़ने और हटाने के तरीकों को पॉप्युलेट किया गया था, लेकिन raise नहीं? क्या यह काम करने के लिए मुझे कुछ खास करना है?

संपादित करें: यदि यह महत्वपूर्ण है, तो यहां प्रतिनिधि, वर्ग और घटनाओं का मूल (मूल) रूप है जो मैं सी # परत में उपयोग कर रहा हूं।

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

संपादित करें टिप्पणी और फिर से पढ़ने सवाल के बाद:

यह सामान्य है कि घटना के लिए बढ़ाने विधि शून्य है।

यह विधि आमतौर पर सी # ईवेंट कीवर्ड या विजुअल बेसिक इवेंट कीवर्ड के साथ घोषित घटनाओं के लिए शून्य हो जाती है। ऐसा इसलिए है क्योंकि सी # और विजुअल बेसिक कंपाइलर्स डिफ़ॉल्ट रूप से ऐसी विधि उत्पन्न नहीं करते हैं।

(source)

मुझे डर है कि यह एक वर्ग के एक ईवेंट सक्रिय करने के लिए मुश्किल हो सकता है कर रहा हूँ। क्योंकि यह वास्तव में .NET में घटनाओं की अवधारणा को तोड़ रहा है - जो कहता है कि वर्ग स्वयं ही अपने स्वयं के कार्यक्रम को आग लगा सकता है। असल में, सी # से भी अन्य वर्ग की घटना को उठाना मुश्किल है।

संकल्पनात्मक रूप से, ईवेंट add_handler और remove_handler विधियों की जोड़ी हैं जहां आप ईवेंट की परिस्थितियों के दौरान कॉल करने वाले प्रतिनिधियों को निर्दिष्ट करते हैं। यह वर्ग तक है कि यह घटनाओं को कैसे लागू करता है। तकनीकी रूप से, यह सिर्फ एक निजी प्रतिनिधि क्षेत्र है, AFAIK। आप इसे ढूंढने का प्रयास कर सकते हैं।

मुझे यकीन नहीं है कि यह एक उचित दृष्टिकोण है, लेकिन How do I raise an event via reflection in .NET/C#? में उत्तरों में से एक का वर्णन करता है कि प्रतिबिंब का उपयोग करके ईवेंट कैसे बढ़ाया जाए। आप इसे mono_class/mono_field कॉल, आदि में रूपांतरित करने का प्रयास कर सकते हैं।

+0

नहीं के साथ मोनो विधि को पकड़ा। डिबगिंग के माध्यम से मैंने सत्यापित किया है कि मैं ईवेंट को सही तरीके से वापस प्राप्त कर रहा हूं। बस mono_event_get_raise_method शून्य लौटाता है। get_add_method और get_remove_method वापसी मान। – Jeff

+0

@Jeff ने मेरा उत्तर – Krizz

3

क्रिज का उत्तर सबसे पूरा है। इस तरह मैंने अपने कोड को काम करने के लिए तय किया कि मैं कैसे "उम्मीद" करूंगा।

मैं सी # ओर बदल दिया है:

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 में काफी सम्मेलन है। घटनाओं पर दस्तावेज़ इसका उपयोग करते हैं ([एक घटना बढ़ाना] (http://msdn.microsoft.com/en-us/library/wkzf914z.aspx) और संबंधित [कैसे करें] (http://msdn.microsoft.com /en-us/library/9aackb16.aspx)), और यह फ्रेमवर्क कक्षाओं में भी पूरे स्थान पर उपयोग किया जाता है।मामूली तरफ: नामकरण सम्मेलन घटनाओं के क्षेत्र में 'प्रवेश' और 'बाहर निकलने' के 'सही "नाम बनाएंगे, और' ऑनइंटरिंग()'/'ऑनएक्सिटिंग 'का उपयोग उन तरीकों के लिए किया जाना चाहिए। – millimoose

संबंधित मुद्दे