2011-01-06 3 views
9

नहीं कहा जाता है मेरे पास एक .bpl के भीतर एक इकाई है, और मुझे एक नए फ़ंक्शन के लिए एक स्ट्रिंगलिस्ट की आवश्यकता है जिसे मैंने लिखा था। मैं ऐप के जीवनकाल के लिए जारी रखने के लिए स्ट्रिंगलिस्ट चाहता हूं, ताकि प्रत्येक कॉल पूर्व कॉल के बारे में बता सके।डेल्फी इकाई प्रारंभिकता हमेशा

तो यह इकाई के भीतर विश्व स्तर पर घोषित की गई है, और मैं प्रारंभ अनुभाग में प्रारंभ कर देते हैं:

var 
    ProductLookup : TStrings; 
... 

function foo : boolean; 
begin 
    result := (ProductLookup.IndexOfName('bar') >=0); //blow up here. It's nil. Why? 
end; 
.... 

initialization 
    ProductLookup := TStringList.Create; // This should get run, but doesn't. 

finalization 
    FreeAndNil(ProductLookup); 

end. 

जब मैं इकाई यह परीक्षण किया है, सब कुछ ठीक था। लेकिन जब यह मुख्य ऐप से चलाया जाता है, तो मैं एक्सेस उल्लंघन के साथ उड़ रहा था क्योंकि स्ट्रिंगलिस्ट शून्य थी। तो अब मैं foo फ़ंक्शन में शून्य की जांच कर रहा हूं और यदि आवश्यक हो तो बनाना चाहता हूं। लेकिन मुझे नुकसान हुआ है कि क्यों शुरुआत मेरे लिए काम नहीं कर रही है। मैंने शुरुआत में एक डीबग संदेश डाला है, और जब यह बीपीएल के रूप में लोड होता है तो यह नहीं चलता है, लेकिन अगर मैं सीधे अपने dUnit exe में संकलित करता हूं तो चला जाता है। कोई विचार? Delphi2005।

+3

रोब कैनेडी के जवाब चेक आउट यहाँ: http://groups.google.com/group/borland.public.delphi.language.delphi.general/browse_thread/thread/5f73d43146d4d8dc/cc4740216011f633?hl=en&ie=UTF- 8 और क्यू = डेल्फी + बीपीएल + प्रारंभिकरण –

उत्तर

24

डेरियन मुझे याद दिलाता है कि I've answered this before: ऑपरेटिंग सिस्टम जुड़े EXE लोड हो रहा है के भाग के रूप बीपीएल लोड करता है

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

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

इस समस्या को हल करने के लिए, आप SysUtils इकाई में InitializePackage फ़ंक्शन को कॉल करके पैकेज की इकाइयों को स्वयं शुरू कर सकते हैं। इसे एक मॉड्यूल हैंडल की आवश्यकता होती है, जिसे आप GetModuleHandle एपीआई फ़ंक्शन को कॉल करके प्राप्त कर सकते हैं। वह फ़ंक्शन केवल उन इकाइयों के प्रारंभिक अनुभागों को कॉल करेगा जिन्हें पहले ही प्रारंभ नहीं किया गया है। वैसे भी, मेरा अवलोकन है।

यदि आप InitializePackage पर कॉल करते हैं, तो आपको FinalizePackage भी कॉल करना चाहिए। जब आपका पैकेज अनलोड हो जाता है, तो अंतिमकरण अनुभाग उन सभी इकाइयों के लिए बुलाए जाएंगे जिन्हें स्वचालित रूप से प्रारंभ किया गया था।

यदि ओएस स्वचालित रूप से आपके पैकेज को लोड नहीं करता है, तो आप इसे LoadPackage फ़ंक्शन के साथ लोड कर रहे हैं। यह आपके लिए सभी पैकेज की इकाइयों को आरंभ करता है, इसलिए आपको InitializePackage स्वयं को कॉल करने की आवश्यकता नहीं है।इसी तरह, UnloadPackage आपके लिए सब कुछ अंतिम रूप देगा।

+0

आपको मेरा +1 मिला! :) –

+0

बहुत बढ़िया - धन्यवाद। –

0

आप बीपीएल कैसे लोड कर रहे हैं? क्या आप इसे लोड करने के लिए डेल्फी में छोड़ रहे हैं या आप मैन्युअल रूप से बीपीएल लोड कर रहे हैं? यदि आप मैन्युअल रूप से बीपीएल लोड कर रहे हैं, तो क्या आप इसे "सीधी" डीएलएल के रूप में लोड कर रहे हैं या क्या आप इसे लोडफैकेज का उपयोग डेल्फी पैकेज के रूप में लोड करने के लिए कर रहे हैं? मुझे लगता है कि या तो वीसीएल लोड (इसे प्रसंस्करण की आवश्यकता के माध्यम से) या लोडपैकेज का उपयोग प्रारंभिक वर्गों को वीसीएल द्वारा चलाने के लिए आवश्यक है ...

1

बीपीएल में प्रत्येक इकाई को प्रारंभिक रूप से प्रारंभ नहीं किया जाएगा कुछ परिस्थितियों। अगर मुझे लगता है, तो मैं कहूंगा कि यह बीपीएल आपके कार्यक्रम से लोड समय पर जुड़ा हुआ है और बाद में गतिशील रूप से लोड नहीं हुआ है? प्रोग्राम के में उपयोग की जा रही इकाई का नाम डालने का प्रयास करें, डीपीआर में सूची का उपयोग करें। इसे ठीक करना चाहिए।

+0

यहां जटिलता यह है कि लगभग 100 अलग-अलग EXEs और .BPLs जो इस विशेष का उपयोग करते हैं। बीपीएल और मुझे उन्हें पुनर्निर्माण करने की अनुमति नहीं है। तो समझदार दृष्टिकोण हमेशा काम नहीं करेंगे। हालांकि अच्छा विचार, और सामान्य रूप से एक अच्छी तकनीक के लिए +1 होगा। –

3

केवल गुणवत्ता केंद्र में एक संदर्भ मिला, लेकिन और भी हो सकता है। लोडपैकेज संदर्भित वर्कअराउंड शामिल है।

http://qc.embarcadero.com/wc/qcmain.aspx?d=61968

+0

मेरी समस्या की तरह दिखता है। +1 –

+0

ध्यान दें कि [QualityCentral अब बंद कर दिया गया है] (https://community.embarcadero.com/blogs/entry/quality-keeps-moving-forward), इसलिए आप 'qc.embarcadero.com 'तक नहीं पहुंच सकते अब लिंक यदि आपको पुराने क्यूसी डेटा तक पहुंच की आवश्यकता है, तो [QCScraper] (http://www.uweraabe.de/Blog/2017/06/09/how-to-save-qualitycentral/) देखें। –