मुझे SysUtils इकाई को अंतिम रूप देने के बाद अपना कोड निष्पादित करने की आवश्यकता है।रन-टाइम पैकेज के साथ संकलित अनुप्रयोग के लिए यूनिट अंतिमकरण आदेश?
मैं अलग इकाई में मेरे कोड डाला है और डीपीआर-फ़ाइल का उपयोग करता है खंड में पहले यह शामिल है, इस तरह:
project Project1;
uses
MyUnit, // <- my separate unit
SysUtils,
Classes,
SomeOtherUnits;
procedure Test;
begin
//
end;
begin
SetProc(Test);
end.
MyUnit इस तरह दिखता है:
unit MyUnit;
interface
procedure SetProc(AProc: TProcedure);
implementation
var
Test: TProcedure;
procedure SetProc(AProc: TProcedure);
begin
Test := AProc;
end;
initialization
finalization
Test;
end.
ध्यान दें कि MyUnit कोई उपयोग नहीं है।
यह सामान्य विंडोज एक्सई, कोई कंसोल नहीं है, बिना फॉर्म के और डिफ़ॉल्ट रन-टाइम पैकेज के साथ संकलित। MyUnit किसी भी पैकेज का हिस्सा नहीं है (लेकिन मैंने इसे पैकेज से भी उपयोग करने का प्रयास किया है)।
मुझे उम्मीद है कि MyUnit का अंतिमकरण अनुभाग SysUtils के अंतिमकरण अनुभाग के बाद निष्पादित किया जाएगा। डेल्फी की मदद मुझे बताती है।
हालांकि, यह हमेशा ऐसा नहीं होता है।
मेरे पास 2 टेस्ट ऐप्स हैं, जो उपयोग में सूचीबद्ध टेस्ट रूटीन/डीआरपी-फाइल और इकाइयों में कोड द्वारा थोड़ा अलग हैं। हालांकि, MyUnit सभी मामलों में पहले सूचीबद्ध है।
एक आवेदन के रूप में उम्मीद से चलाया जाता है: -> FinalizeUnits -> ... अन्य इकाइयों ... -> SysUtils के अंतिम रूप दिए जाने -> MyUnit के अंतिम रूप दिए जाने - Halt0> ... अन्य इकाइयों ...
लेकिन दूसरा नहीं है। MyUnit का अंतिमकरण SysUtils के अंतिमकरण से पहले लागू किया गया है। वास्तविक कॉल श्रृंखला इस तरह दिखती है: Halt0 -> FinalizeUnits -> ... अन्य इकाइयां ... -> SysUtils का अंतिमकरण (छोड़ दिया गया) -> MyUnit का अंतिमकरण -> ... अन्य इकाइयां ... -> SysUtils का अंतिमकरण (निष्पादित)
दोनों परियोजनाओं में बहुत ही समान सेटिंग्स हैं। मैंने अपने मतभेदों को हटाने/कम करने के लिए बहुत कुछ करने की कोशिश की, लेकिन मुझे अभी भी इस व्यवहार का कोई कारण नहीं दिख रहा है।
मैंने इसे डीबग करने का प्रयास किया है और यह पता चला है कि: ऐसा लगता है कि प्रत्येक इकाई के पास कुछ प्रकार की संदर्भ गणना होती है। और ऐसा लगता है कि InitTable में एक ही इकाई के गुणा संदर्भ शामिल हैं। जब SysUtils के अंतिमकरण खंड को पहली बार बुलाया जाता है - यह संदर्भ काउंटर बदलता है और कुछ भी नहीं करता है। फिर MyUnit का अंतिम रूप निष्पादित किया जाता है। और फिर SysUtils फिर से कहा जाता है, लेकिन इस बार रेफरी गिनती शून्य तक पहुंच और अंतिम रूप दिए जाने अनुभाग निष्पादित होने
Finalization: // SysUtils' finalization
5003B3F0 55 push ebp // here and below is some form of stub
5003B3F1 8BEC mov ebp,esp
5003B3F3 33C0 xor eax,eax
5003B3F5 55 push ebp
5003B3F6 688EB50350 push $5003b58e
5003B3FB 64FF30 push dword ptr fs:[eax]
5003B3FE 648920 mov fs:[eax],esp
5003B401 FF05DCAD1150 inc dword ptr [$5011addc] // here: some sort of reference counter
5003B407 0F8573010000 jnz $5003b580 // <- this jump skips execution of finalization for first call
5003B40D B8CC4D0350 mov eax,$50034dcc // here and below is actual SysUtils' finalization section
...
किसी को भी इस मुद्दे पर प्रकाश टुकड़ा कर सकते हैं कर सकते हैं? क्या मैं कुछ भूल रहा हूँ?
> कोई विशेष कारण है कि अपने MyUnit SysUtils के बाद अंतिम रूप देने की जरूरत है? हाँ। यह mem-leaking चेक है। – Alex
@Alexander: क्या यह कुछ खास कर रहा है कि आप FullDebugMode में FastMM के साथ नहीं मिल सकते हैं? –
> क्या यह कुछ खास कर रहा है कि आप FullDebugMode में FastMM के साथ नहीं मिल सकते हैं? यह सवाल नहीं है, जिसे मैं पूछ रहा हूं, तो चलो इसे अलग रखें। फास्टएमएम ने मेरे दूसरे ऐप में बिल्कुल उसी कारण से काम नहीं किया: इसे बहुत जल्दी कहा जाता है। – Alex