2012-04-17 8 views
7

मैंने अपने अनुप्रयोगों के लिए एक स्क्रिप्टभाषा लिखी और मेरा लक्ष्य स्क्रिप्ट में डेल्फी से किसी भी प्रकार को प्रकाशित करना संभव बनाना है। मैं इस कार्य को स्वचालित करने के लिए आरटीआई का उपयोग करता हूं। स्क्रिप्ट से किसी विधि को खोजने और कॉल करने के लिए कक्षाओं जैसे किसी भी उदाहरण के लिए मैं निम्नलिखित कोड का उपयोग करता हूं।डेल्फी - प्रति नाम रिकॉर्ड विधि को आमंत्रित करें

var Info : TRttiType; 
    Meth : TRttiMethod; 
    Param : TArray<TValue>; 
    Result : TValue; 
    AnyClass : TClass; 
begin 
    ... 
    Info := RttiContext.GetType(AnyClass); 
    Meth := Info.GetMethod('AMethod'); 
    Setlength(Param, 1); 
    Param[0] := TValue.From<Integer>(11); 
    Result := Meth.Invoke(ClassInstance, Param); 
    ... 
end; 

लेकिन एक रिकार्ड इस कोड काम नहीं करता है के साथ, क्योंकि TRttiMethod प्रकार रिकॉर्ड प्रकारों के लिए एक आह्वान() विधि प्रदान नहीं करता है। मैं रिकॉर्ड प्रकार से Info.GetMethod ('AMethod') द्वारा विधि infos तक पहुंच सकता हूं।

TRecordType = record 
    Field1, Field2 : single; 
    procedure Calc(Value : integer); 
end; 

तो किसी को पता है एक रिकार्ड से एक विधि आह्वान करने के लिए अगर मैं methodName या methodaddress है एक तरह से:
उदाहरण के लिए मैं इस तरह की एक रिकॉर्ड है?

+0

क्या आपने अभी [DWScript] (http://code.google.com/p/dwscript/) को फिर से शुरू किया था? –

+0

संकेत के लिए धन्यवाद, लेकिन मुझे डीडब्ल्यूस्क्रिप्ट पता है। मेरी भाषा को एक डेल्फी प्रोग्राम के लिए एक स्क्रिप्ट करने योग्य इंटरफ़ेस के रूप में लक्षित किया गया है, जहां AObject.AFunction.AObject.DoSomething की तरह संरचनाएं संभव हैं। – DragonFlyOfGold

+2

मैंने सोचा था कि DWScript वह सब कर सकता है, लेकिन शायद मैं इतना बताते हुए रिकॉर्ड पर तरीकों के लिए कोई RTTI है कि वहाँ पर यहाँ गलत हूँ –

उत्तर

12

डेल्फी दस्तावेजों टिप्पणी में तैनात ऊपर मैं System.Rtti में डेल्फी प्रकार TRttiRecordMethod को करीब से देख ले लिया में लिंक की खोज के बाद। यह विधि DispatchInvoke() प्रदान करता है और यह विधि एक सूचक की अपेक्षा करता है। तो निम्नलिखित कोड काम करता है:

TRecordType = record 
    Field1, Field2 : single; 
    procedure Calc(Value : integer);  
end; 


    Meth : TRttiMethod; 
    Para : TRttiParameter; 
    Param : TArray<TValue>; 
    ARec : TRecordType; 
begin 
    Info := RttiContext.GetType(TypeInfo(TRecordType)); 
    Meth := Info.GetMethod('Calc'); 
    Setlength(Param, 1); 
    Param[0] := TValue.From<Integer>(12); 
    Meth.Invoke(TValue.From<Pointer>(@ARec), Param); 
end; 

आप एक स्थिर विधि या अतिभारित ऑपरेटर कोड काम नहीं करता कॉल करने के लिए चाहते हैं। डेल्फी आंतरिक रूप से हमेशा पैरामीटर सूची में स्वयं सूचक जोड़ता है, लेकिन इससे accessviolation का कारण बनता है। तो इसके बजाय इस कोड का उपयोग करें:

Meth : TRttiMethod; 
    Para : TRttiParameter; 
    Param : TArray<TValue>; 
    ARec : TRecordType; 
begin 
    Info := RttiContext.GetType(TypeInfo(TRecordType)); 
    Meth := Info.GetMethod('&op_Addition'); 
    ... 
    Meth.Invoke(TValue.From<Pointer>(@ARec), Param); 
    Result := System.Rtti.Invoke(Meth.CodeAddress, Param, Meth.CallingConvention, Meth.ReturnType.Handle, Meth.IsStatic); 
end;  
+0

धन्यवाद, यह वास्तव में मुझे एक एसओएपी वेब सेवा को गतिशील रूप से कॉल करने के तरीके के लिए मेरी खोज में मदद करता है! – dahook

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