تهيئة وحدة دلفي لا تسمى دائمًا
-
30-09-2019 - |
سؤال
لدي وحدة داخل .bpl ، وأحتاج إلى قائمة سلسلة لوظيفة جديدة كتبتها. أريد أن تستمر قائمة String List لعمر التطبيق ، بحيث يمكن لكل مكالمة أن تبني على ما تم العثور عليه المكالمة السابقة.
لذلك تم الإعلان عنه عالميًا داخل الوحدة ، وأهيئته في قسم التهيئة ، مثل هذا:
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.
عندما اختبرتها الوحدة ، كان كل شيء على ما يرام. ولكن عندما يتم تشغيله من التطبيق الرئيسي ، كنت أتفاجأ بانتهاك الوصول لأن قائمة السلسلة كانت لا شيء. حتى الآن أنا ألجأ إلى التحقق من NIL في وظيفة FOO وإنشاء إذا لزم الأمر. لكنني في حيرة من السبب وراء عدم عمل التهيئة بالنسبة لي. لقد وضعت رسالة تصحيح مباشرة هناك في التهيئة ، ولا يتم تشغيلها عندما يتم تحميل هذا بمثابة BPL ، ولكن يتم تشغيله إذا قمت بالتجميع مباشرة في Dunit Exe. أيه أفكار؟ Delphi2005.
المحلول
يذكرني داري ذلك لقد أجبت هذا من قبل:
إذا قام نظام التشغيل بتحميل BPL كجزء من تحميل EXE المرتبط ، فلن يتم استدعاء جميع أقسام التهيئة. بدلاً من ذلك ، يتم استدعاء فقط الأقسام من الوحدات التي يتم استخدامها بشكل صريح من قبل شيء آخر في البرنامج.
إذا قام الرمز في قسم التهيئة بتسجيل فئة ، ثم تشير فقط إلى تلك الفئة بشكل غير مباشر ، على سبيل المثال من خلال البحث عنها بالاسم في قائمة ، قد لا يتم استدعاء قسم تهيئة الوحدة. يجب إضافة هذه الوحدة إلى أي فقرة "استخدام" في البرنامج الخاص بك أن تحل هذه المشكلة.
للتغلب على هذه المشكلة ، يمكنك تهيئة وحدات الحزمة بنفسك عن طريق الاتصال
InitializePackage
وظيفة ، في وحدة sysutils. يتطلب مقبض الوحدة النمطية ، والتي يمكنك الحصول عليها عن طريق الاتصالGetModuleHandle
وظيفة API. ستستدعي هذه الوظيفة فقط أقسام التهيئة للوحدات التي لم تتم تهيئتها بالفعل. هذه ملاحظتي ، على أي حال.إذا اتصلت
InitializePackage
, ، ثم يجب عليك الاتصال أيضًاFinalizePackage
. عندما يتم تفريغ الحزمة الخاصة بك ، سيتم استدعاء أقسام الانتهاء لجميع الوحدات التي تمت تهيئة تلقائيًا.إذا كان نظام التشغيل ليس قم بتحميل الحزمة الخاصة بك تلقائيًا ، ثم تقوم بتحميلها باستخدام
LoadPackage
وظيفة. يقوم بتهيئة جميع وحدات الحزمة لك ، لذلك لا تحتاج إلى الاتصالInitializePackage
نفسك. على نفس المنوال،UnloadPackage
سوف ينتهي كل شيء من أجلك.
نصائح أخرى
وجدت فقط مرجع واحد في الجودة المركزية ، ولكن قد يكون هناك المزيد. يشمل تحميل apriced حل الحل البديل.
لن يتم بالضرورة تهيئة كل وحدة في BPL ، في ظل ظروف معينة. إذا اضطررت إلى تخمين ، أقول إن هذا BPL مرتبط ببرنامجك في وقت التحميل ولا يتم تحميله ديناميكيًا لاحقًا؟ حاول وضع اسم الوحدة التي تستخدمها في البرنامج الاستخدامات قائمة في كوريا الديمقراطية. يجب أن يصلحه.
كيف تقوم بتحميل BPL؟ هل تتركها إلى دلفي للقيام بالتحميل أم أنك تقوم بتحميل BPL يدويًا؟ إذا كنت تقوم بتحميل BPL يدويًا ، فهل تقوم بتحميله كـ DLL "مستقيم" أم أنك تستخدم LoadPackage لتحميله كحزمة Delphi؟ أعتقد أن السماح لـ VCL بتحميله (من خلال المعالجة المتطلبات) أو استخدام LoadPackage مطلوب لأقسام التهيئة التي يتم تشغيلها بواسطة VCL ...