Friday, 15 March 2013

Delphi Class Helper RTTI GetMethod -


चलो कहना है कि मेरे पास एक नमूना वर्ग सहायक है

  TSampleClassHelper = TSampleClass सार्वजनिक प्रक्रिया के लिए वर्ग सहायक SomeHelper; समाप्त;   

मैं निम्नलिखित करता हूं:

  var obj: TSampleClass; शुरू obj: = TSampleClass.Create; obj.SomeHelper; समाप्त;   

और यह अपेक्षित रूप से कार्य करता है।

लेकिन मैं इसके बजाय सहायक विधि को खोलने के लिए RTTI का उपयोग कैसे कर सकता हूं? निम्न कार्य करने के लिए प्रतीत नहीं होता है, GetMethod रिटर्न शून्य।

  var obj: TSampleClass; Ctx: TRTTIContext; रीटाइप: टीआरटीटीआईपी; Rmethod: TRTTimethod; शुरू obj: = TSampleClass.Create; rtype: = ctx.GetType (obj.ClassType); rmethod: = rtype.GetMethod ( 'SomeHelper'); // rmethod शून्य है! समाप्त;   

तो क्या आरटीटीआई क्लास हेल्पर्स में परिभाषित विधियों के लिए काम नहीं करता है?

धन्यवाद।

कारण आपका कोड वापस देता है शून्य विधि यह है कि ऑब्जेक्ट के प्रकार में SomeHelper नाम की कोई विधि शामिल नहीं है उस पद्धति में शामिल प्रकार सहायक है।

तो, आप इसे लिख सकते हैं जो एक गैर-नील विधि वापस करेगा:

  obj: = TSampleClass.Create; rtype: = ctx.GetType (TypeInfo (TSampleClassHelper)); rmethod: = rtype.GetMethod ( 'SomeHelper');   

बेशक, आपको तुरंत पहली समस्या दिखाई देनी चाहिए, अर्थात् एक संकलन समय निर्दिष्ट प्रकार, TSampleClassHelper का उपयोग करें। क्या हम उदाहरण के प्रकार के आधार पर रनटाइम पर TSampleClassHelper को खोजने के लिए RTTI का उपयोग कर सकते हैं? नहीं, हम ऐसा नहीं कर सकते हैं, जैसा कि मैं नीचे समझाऊंगा।

यहां तक ​​कि अगर हम इसे एक तरफ रख सकते हैं, जहां तक ​​मैं देख सकता हूं, आरटीटीआई का उपयोग करने के तरीके को लागू करने का कोई रास्ता नहीं है। यदि आप rmethod.Invoke (obj, []) को कॉल करते हैं, तो कोड में TRttiInstanceMethodEx.DispatchInvoke सहायक विधि को कॉल करने का एक प्रयास अवरुद्ध करता है। यह इसे ब्लॉक करता है क्योंकि यह आदेश देता है कि उदाहरण का प्रकार विधि के वर्ग के साथ संगत नहीं है। उचित कोड है:

  यदि (cls & lt; & gt; शून्य) और नहीं cls.InheritsFrom (TRttiInstanceType (माता पिता)। मैटैलास टाइप) तो EInvalidCast.CreateRes (@ SInvalidCast) बढ़ा;   

ठीक है, आप rmethod.CodeAddress के साथ सहायक विधि का कोड पता प्राप्त कर सकते हैं, लेकिन आपको उस विधि को लागू करने के लिए कोई दूसरा रास्ता खोजने की आवश्यकता होगी। उचित हस्ताक्षर के साथ एक विधि में इसे डालने और इसे लागू करने के लिए यह आसान है। लेकिन किसी भी मामले में rmethod.CodeAddress से क्यों परेशान? क्यों नहीं TSomeHelperClass.SomeMethod का उपयोग करें और आरटीटीआई को लूप से बाहर निकाल दें?

चर्चा

हेल्पर रिज़ॉल्यूशन आधार पर स्थिर रूप से किया जाता है संकलन के बिंदु पर सक्रिय सहायक। एक बार जब आप आरटीटीआई का उपयोग कर सहायक पद्धति का उपयोग करने का प्रयास करते हैं, तो कोई सक्रिय सहायक नहीं है आपने लंबे समय से संकलन समाप्त कर लिया है तो आपको यह तय करना होगा कि किस सहायक वर्ग का उपयोग करना है। किस बिंदु पर, आपको आरटीटीआई की आवश्यकता नहीं है।

यहां मूलभूत मुद्दा यह है कि वर्ग सहायक पद्धति संकल्प मूल रूप से संकलक के संदर्भ के प्रयोग से किया गया एक स्थिर प्रक्रिया है। रन-टाइम में कंपाइलर संदर्भ नहीं होने के कारण, कक्षा सहायक पद्धति का रिज़ॉल्यूशन RTTI का उपयोग नहीं किया जा सकता।

इसमें अधिक अंतर्दृष्टि के लिए एलेन बॉवर का उत्तर यहां पढ़ता है: < / html>

No comments:

Post a Comment