2010-11-09 10 views
11

में एक वस्तु के लिए एक इंटरफेस कास्ट करने के लिए डेल्फी 2009 में मैं एक IInterface जो मैं करने के लिए अंतर्निहित TObjectकैसे डेल्फी

जाहिर TObject(IInterface) का उपयोग डेल्फी 2009 में काम नहीं करता है (यह चाहिए था कास्ट करना चाहते हैं के लिए एक संदर्भ है हालांकि डेल्फी 2010 में काम)

मेरी खोज मुझे a function that should do the trick पर ले जाती है, लेकिन यह मेरे लिए काम नहीं करती है, जब मैं लौटे ऑब्जेक्ट पर विधियों को कॉल करने का प्रयास करता हूं तो मुझे एवी मिलता है।

मैं वास्तव में कक्षाएं नहीं संशोधित कर सकते हैं और मुझे पता है यह टूट जाता है कि OOP

उत्तर

18

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

interface 

type 
    IGetObject = interface 
    function GetObject: TObject; 
    end; 

    TSomeClass = class(TInterfacedObject, IGetObject) 
    public 
    function GetObject: TObject; 
    end; 

implementation 

function TSomeClass.GetObject: TObject; 
begin 
    Result := Self; 
end; 
+1

मैं वास्तव में पहले से ही इस समाधान का उपयोग कर समाप्त हुआ, लेकिन अभी तक अपना जवाब पोस्ट करने के लिए नहीं मिला। आप को सलाम! – Yona

2

Hallvard के हैक कैसे डेल्फी संकलक कोड उत्पन्न करने के लिए बहुत विशिष्ट है। यह अतीत में उल्लेखनीय रूप से स्थिर रहा है, लेकिन ऐसा लगता है जैसे उन्होंने डेल्फी 200 9 में कुछ महत्वपूर्ण बदल दिया। मेरे पास केवल 2007 स्थापित है, और उसमें, हॉलवार्ड का कोड ठीक काम करता है।

क्या GetImplementingObject वापसी शून्य है?

यदि ऐसा है, तो यदि आप GetImplementingObject रूटीन में केस स्टेटमेंट पर ब्रेक-पॉइंट डीबग और सेट करते हैं, तो QueryInterfaceThunk.AddInstruction का मान डीबगर में मूल्यांकन करता है?

+0

यह शून्य नहीं लौटाता है, ऐसा लगता है कि यह गलत स्मृति पता देता है, क्योंकि मैं ऑब्जेक्ट का कुछ डेटा देख सकता हूं लेकिन अन्य डेटा सिर्फ – Yona

+1

200 9 को एक नया छुपा सूचक फ़ील्ड (मॉनिटर समर्थन के लिए) पेश किया गया है। आपको इसके लिए खाते में विधि समायोजित करना चाहिए। – alex

+0

धन्यवाद एलेक्स, लेकिन यह विधि डेल्फी में मेरी विशेषज्ञता से परे है। क्या आप विस्तारित कर सकते हैं कि मुझे क्या समायोजित करना चाहिए? – Yona

3

संक्षेप में: आपको उस विधि के साथ इंटरफ़ेस नहीं जोड़ना चाहिए या आपके लिए पॉइंटर वापस नहीं करना चाहिए। कुछ और हैकर है।

ध्यान दें कि एक इंटरफेस "उदाहरण" किसी अन्य भाषा में लागू किया जा सकता है (वे कॉम संगत कर रहे हैं) और/या कुल मिलाकर प्रक्रिया आदि आदि

बाहर कुछ के लिए एक ठूंठ हो सकता है: एक अंतरफलक उदाहरण केवल इंटरफ़ेस से सहमत हैं और कुछ भी नहीं, निश्चित रूप से डेल्फी टॉब्जेक्ट उदाहरण

+0

मुझे पता है कि यह एक हैक है और यह चीजों को तोड़ सकता है। मैंने पूछा कि मुझे कैसे नहीं करना चाहिए। – Yona

-1
var 
    N, F: NativeInt; // NativeInt is Integer(in delphi 32bit) 
    S: TObject; 
begin 
    N := NativeInt(Args[0].AsInterface) - 12; 
    {subtract 12 byte to get object address(in x86 ,1 interface on class) } 
    S := TObject(N);  
    writeln(S.ToString); 

end; 
+0

यह कुछ कंपाइलर जेनरेट कोड के लिए काम कर सकता है, लेकिन दूसरों को नहीं। जेनरेट कोड से $ 0C निरंतर प्राप्त करना हमेशा बेहतर होता है। –

15

आप ठीक कह रहे हैं। डेल्फी 2010 के साथ शुरुआत, आप ऑपरेटर के रूप में उपयोग करने में सक्षम हैं, उदा। aObject := aInterface as TObject या यहां तक ​​कि aObject := TObject(aInterface) के माध्यम से।

यह as ऑपरेटर वस्तु दृष्टान्त को पुनः प्राप्त करने, TObject.GetInterface का एक उन्नत संस्करण है, जो System.pas इकाई की पूर्व डेल्फी 2010 तक देखें स्रोत कोड मौजूद नहीं है देखने के लिए यह कैसे काम करता बुला एक विशेष छिपा इंटरफ़ेस GUID (ObjCastGUID) का उपयोग करें।

मैंने डेल्फी 6 तक XE2, including Delphi 2009 तक कुछ कोड प्रकाशित किया है।

देखें http://blog.synopse.info/post/2012/06/13/Retrieve-the-object-instance-from-an-interface

+0

आपके डेल्फी 6 वर्कअराउंड के लिए धन्यवाद। यह काम करता हैं !!! – geekobi

3

वहाँ एक अच्छा विकल्प जब आप जानते हैं को लागू करने वस्तु एक TComponent वंशज है।तो अगर आप

TComponent = class(TPersistent, IInterface, IInterfaceComponentReference) 

: (self वापस जाने के लिए और लागू)

IInterfaceComponentReference = interface 
    ['{E28B1858-EC86-4559-8FCD-6B4F824151ED}'] 
    function GetComponent: TComponent; 
end; 

और फिर यह TComponent में घोषित की गई:

आप IInterfaceComponentReference इंटरफ़ेस है, जो Classes इकाई में परिभाषित किया गया है का उपयोग कर सकते पता कार्यान्वयन ऑब्जेक्ट TComponent है तो आप यह कर सकते हैं:

function InterfaceToComponent(const AInterface: IInterface): TComponent; 
var 
    vReference: IInterfaceComponentReference; 
begin 
    if Supports(AInterface, IInterfaceComponentReference, vReference) then 
    result := vReference.GetComponent 
    else 
    result := nil; 
end;