2009-04-17 15 views
12

System.pas फ़ाइल में हार्ड-कोडित वीएमटी ऑफ़सेट पर उचित जानकारी है, लेकिन ऐसा लगता है कि वास्तव में वीएमटी की संरचना के बारे में बहुत कुछ नहीं लगता है। मैं वास्तव में क्या जानना चाहता हूं, क्या रनटाइम पर वीएमटी के आकार का पता लगाने का कोई तरीका है, या दूसरे शब्दों में, किसी दिए गए वर्ग के लिए कितने आभासी तरीके मौजूद हैं?डेल्फी वीएमटी की संरचना पर मुझे जानकारी कहां मिल सकती है?

उत्तर

13

से शुरू कर सकते हैं वीएमटी संरचना के बारे में क्या आप जानना चाहते हैं? आप यह भी जानते हैं कि यह एक आंतरिक कार्यान्वयन विवरण है जो परिवर्तन के अधीन है (और समय के साथ बदल गया है)।

function GetVirtualMethodCount(AClass: TClass): Integer; 
begin 
    Result := (PInteger(Integer(AClass) + vmtClassName)^ - 
    (Integer(AClass) + vmtParent) - SizeOf(Pointer)) div SizeOf(Pointer); 
end; 

यह काम करता है क्योंकि मुझे पता है कि स्ट्रिंग वर्ग के नाम का प्रतिनिधित्व रखा गया है होती हैं:

अपने विशिष्ट सवाल का जवाब करने के लिए, यहाँ किसी वर्ग के लिए आभासी तरीकों की संख्या को खोजने के लिए एक आसान तरीका है वीएमटी में सभी वर्चुअल विधि वैक्टरों का तुरंत पालन करें।

मुझे यह भी पता है कि सभी टॉब्जेक्ट्स पर 11 वर्चुअल विधियां (डी 200 9, 9 के लिए 9 और 7 के लिए) हैं जो वीएमटी पॉइंटर से नकारात्मक रूप से ऑफसेट हैं।

vmtParent संदर्भ के लिए कारण है कि।

अंत में, एक TClass वर्ग संदर्भ का उपयोग करके, आप किसी भी TObject व्युत्पन्न वर्ग इस समारोह में पारित और आभासी तरीकों की संख्या प्राप्त कर सकते हैं।

+0

VmtEquals? मैंने पहले कभी नहीं सुना है। डेल्फी 200 9 के लिए TObject में दो नए आभासी तरीकों में से एक बराबर है? –

+0

हां। कुछ जेनेरिक-संबंधित चीजों को काम करने के लिए जरूरी है, मुझे विश्वास है। –

+0

एलन: यह बहुत अच्छा है! मुझे इसकी ही खोज थी। आप कहते हैं कि संरचना बदल सकती है और बदलती है।तो डेल्फी का कौन सा संस्करण उस चाल के लिए काम करता है? –

2

"डेल्फी VMT" पैदावार this के लिए :-P Googling। शायद यह आपको एक शुरुआत देता है।

+2

* ग्रिन * मुझे हॉलवार्ड पसंद है! वह इस तरह की चाल पर अच्छा है। दुर्भाग्यवश, वह उपयोगकर्ता परिभाषित वर्चुअल को "सरणी [0..9 99]" ​​के रूप में परिभाषित करता है, या दूसरे शब्दों में "इससे बड़ा होने की आवश्यकता होगी।" मैं वास्तविक आकार खोजने का एक तरीका ढूंढ रहा हूं। –

0

मुझे याद पुस्तक "संक्षेप में डेल्फी" में डेल्फी VMT बारे में कुछ जानकारी नहीं थी। आप delphi in a nutshell chapter 2 या this

1

मैं इस एक के लिए मेरी अपनी साइट प्लग होगी:

What is the virtual-method table?

यह डेल्फी 2005 के रूप में सही है, मुझे लगता है।

VMT आभासी-विधि संकेत यह मानती है की संख्या देने के किसी भी मूल्य नहीं है। कुछ भी नहीं लेकिन कंपाइलर को उस जानकारी को जानने की जरूरत है, इसलिए रन टाइम पर उपयोग के लिए इसे रिकॉर्ड करने का कोई कारण नहीं है।

9

मैं यकीन है कि Hallvard VMT पर कुछ था। निश्चित रूप से, उसके पास Hack #8: Explicit VMT calls है जो रे Lischner डेल्फी 2 और डेल्फी संक्षेप में में संदर्भ देता है।

यहाँ VMT

type 
    PClass = ^TClass; 
    PSafeCallException = function (Self: TObject; ExceptObject: 
    TObject; ExceptAddr: Pointer): HResult; 
    PAfterConstruction = procedure (Self: TObject); 
    PBeforeDestruction = procedure (Self: TObject); 
    PDispatch   = procedure (Self: TObject; var Message); 
    PDefaultHandler = procedure (Self: TObject; var Message); 
    PNewInstance  = function (Self: TClass) : TObject; 
    PFreeInstance  = procedure (Self: TObject); 
    PDestroy   = procedure (Self: TObject; OuterMost: ShortInt); 
    PVmt = ^TVmt; 
    TVmt = packed record 
    SelfPtr   : TClass; 
    IntfTable   : Pointer; 
    AutoTable   : Pointer; 
    InitTable   : Pointer; 
    TypeInfo   : Pointer; 
    FieldTable  : Pointer; 
    MethodTable  : Pointer; 
    DynamicTable  : Pointer; 
    ClassName   : PShortString; 
    InstanceSize  : PLongint; 
    Parent   : PClass; 
    SafeCallException : PSafeCallException; 
    AfterConstruction : PAfterConstruction; 
    BeforeDestruction : PBeforeDestruction; 
    Dispatch   : PDispatch; 
    DefaultHandler : PDefaultHandler; 
    NewInstance  : PNewInstance; 
    FreeInstance  : PFreeInstance; 
    Destroy   : PDestroy; 
    {UserDefinedVirtuals: array[0..999] of procedure;} 
    end; 

आप हालांकि हैक के बारे में अधिक के लिए अपने लेख पढ़ने के लिए की आवश्यकता होगी के बारे में उनकी हैक की गई संस्करण है।

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