سؤال

لدي وحدة داخل .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 حل الحل البديل.

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

لن يتم بالضرورة تهيئة كل وحدة في BPL ، في ظل ظروف معينة. إذا اضطررت إلى تخمين ، أقول إن هذا BPL مرتبط ببرنامجك في وقت التحميل ولا يتم تحميله ديناميكيًا لاحقًا؟ حاول وضع اسم الوحدة التي تستخدمها في البرنامج الاستخدامات قائمة في كوريا الديمقراطية. يجب أن يصلحه.

كيف تقوم بتحميل BPL؟ هل تتركها إلى دلفي للقيام بالتحميل أم أنك تقوم بتحميل BPL يدويًا؟ إذا كنت تقوم بتحميل BPL يدويًا ، فهل تقوم بتحميله كـ DLL "مستقيم" أم أنك تستخدم LoadPackage لتحميله كحزمة Delphi؟ أعتقد أن السماح لـ VCL بتحميله (من خلال المعالجة المتطلبات) أو استخدام LoadPackage مطلوب لأقسام التهيئة التي يتم تشغيلها بواسطة VCL ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top