في الآونة الأخيرة ، بدأت العمل على Delphi ووجدت أن العديد من الحزم تم استخدامها في البرنامج الأصلي ، لكنني كنت دائمًا في حالة جاهلة. قد يستغرق الأمر بعض الوقت لدراسة هذه القضية. لذا قم أولاً بإدراج الأسئلة التي يجب تحليلها:
ما هي الحقيبة؟ ما هو exe؟ ما هي اختلافات تكوينها؟ ما هي العلاقة بين الحزمة و DCU؟ ماذا يفعل DCP؟ ما هي العلاقة بين هذه الملفات في وقت الترجمة؟ كيف يتم تحميله؟ كيفية تشغيل الحزمة بعد التحميل؟ يمكن أن تصدر DLL ، ولكن لماذا تساعد Delphi في طرح صادرات الحزمة ، ولكن بعض التعليمات البرمجية تستخدم Exprots في الحزمة؟
أولاً ، دعونا نلقي نظرة على عملية تجميع دلفي. هناك نوعان من المشاريع في دلفي: الحزم والبرامج. ابدأ بواحد بسيط ، لنبدأ مع DPR. وفقًا لوثائق مساعدة Delphi ، فإن هيكل ملف DPR النموذجي هو كما يلي:
1 محرر البرنامج ؛
2
3 استخدامات
4 نماذج ، {تغيير إلى QForms في Linux}
5 Reabout في 'reebout.pas' {aboutbox} ،
6 تبقى في "تبقى. pas '{mainform} ؛
7
8 {$ r *.res}
9
10 تبدأ
11 Application.Title: = 'Text Editor' ؛
12 Application.CreateForm (Tmainform ، Mainform) ؛
13 Application.Run ؛
14 نهاية.
من بينها ، من 10 إلى 14 سطرًا ، ابدأ ... النهاية هو مدخل تنفيذ البرنامج بشكل طبيعي. يشير جزء الاستخدامات إلى بعض الوحدات التي يحتاجها البرنامج ، وهو أمر غامض إلى حد ما. يحتاج؟ ثم ستستخدم كل وحدة وحدات أخرى ، ويبدو أن هذه المشكلة أصبحت أكثر تعقيدًا. دعونا نلقي نظرة على بنية رمز المصدر بأكمله أولاً:
أعتقد أن الخطوة الأولى من المترجم هي اجتياز هذا الرسم البياني الموجه ، وتجميع كل وحدة ، إذا لزم الأمر ، وإنشاء DCU المقابلة. أما بالنسبة لهذه القضية "اللازمة" ، فقد اعتقدت في البداية أن بيان استخدام وحدة الاستخدام كان موجودًا ، لكن في وقت لاحق وجدت أنه كان خطأ. لأنه في الحالة أعلاه ، لا تحدد UNIT3 المسار في شرط استخدام UNIT1 ، ولكن لا يزال يتم إنشاء ملف DCU المقابل بشكل صحيح. في وقت لاحق ، يتم استخدام Filemon لمراقبة موقف فتح الملف ، وعملية الاكتشاف هي كما يلي: لكل عقدة في الرسم البياني ، يبحث المترجم في العقد المقابلة في مسار البحث في السمة الحالية - سمة المشروع - مسار المكتبة في المكتبة البيئة.
الآن بعد أن تم الانتهاء من التجميع ، قامت كل وحدة (على سبيل المثال ، ملف PAS) بإنشاء ملف DCU لذلك. عندما يتعلق الأمر بالاتصالات ، فإن المشكلة معقدة. الاتصال الثابت يعني الجمع بين كل هذه DCU معًا. وبهذه الطريقة ، تصبح دعوة وحدة إلى وحدة أخرى مسألة داخلية للبرنامج. هذه الفائدة هي أنها سريعة وبسيطة ، وأن مشاكل مثل المشاركة المتزامنة سهلة التعامل معها. العيب هو أن البرنامج المستهدف كبير ، وإذا تم كتابة برنامج آخر الآن ويمكن إعادة استخدام الوحدة 3 ، فسيتم نسخ UNIT3.DCU مرة أخرى عند الاتصال. وبهذه الطريقة ، عندما يتم تشغيل برنامجين في نفس الوقت ، سيكون هناك نسختان من الوحدة 3 في الذاكرة ، وهي مضيعة. يعني الاتصال الديناميكي أنه عندما يتصل برنامجان ، فإنهما يحتفظان فقط بالإشارات إلى Unit3 ، ولا ينسخون محتوى Unit3. في وقت التشغيل ، قم بتحميل UNIT3 في الذاكرة وجعل البرنامجين شائعين. DLL و BPL هما حلان للاتصالات الديناميكية. المشكلة هي أن الخيار الوحيد للاتصال في Delphi يظهر في قائمة Project | Options | Packages ، وأن الجملة "Build with Runtime Packages" غامضة للغاية. لذلك نحن بحاجة إلى دراسته مرة أخرى.
عندما يتم تنفيذ البرنامج ، يمكننا استخدام View | window debug | moudles لمعرفة الأشياء التي يتم تحميلها في الذاكرة والمحتوى الذي تحتوي عليه.
لكي نكون بسيطين ، قمنا بإعداد برنامج مع الهيكل التالي:
برنامج ProjectExe ؛
يستخدم
الأشكال ،
النوافذ ،
unitformmain في 'unitformmain.pas' {formmain} ؛
{$ r *.res}
يبدأ
application.initialize ؛
application.createform (tformmain ، formmain) ؛
application.run ؛
نهاية.
وحدة UNITFORMMAIN ؛
واجهة
يستخدم
Windows ، stdctrls ، النماذج ، unitformanother ، فئات ، عناصر التحكم ؛
يكتب
tformmain = فئة (tform)
Button1: Tbutton ؛
الإجراءات button1click (المرسل: tobject) ؛
خاص
{إعلانات خاصة}
عام
{الإعلانات العامة}
نهاية؛
var
formmain: tformmain ؛
تطبيق
{$ r *.dfm}
الإجراء tformmain.button1click (المرسل: tobject) ؛
var
Lform: tformanother ؛
يبدأ
lform: = tformanother.create (application) ؛
lform.showmodal ؛
lform.free ؛
نهاية؛
نهاية.
وحدة Unitformanother ؛
واجهة
يستخدم
أشكال
يكتب
tformanother = فئة (tform)
خاص
{إعلانات خاصة}
عام
{الإعلانات العامة}
نهاية؛
تطبيق
{$ r *.dfm}
نهاية.
دعونا نحصل على الأخبار الآن. يتم التحقق من "Build with Runtime Packages" ، والآن وجد أن ملف ProjectExe.exe يحتوي فقط على أربعة أجزاء: نموذجان ، sysinit.pas ، و One Projectexe.dpr ؛ في شجرة العملية: RTL60 و VCL60 ، فإن محتواها هو الوحدات التي ظهرت في الاتصال الثابت الآن. ProjectExe.exe هو 16 كيلو فقط الآن. بمعنى آخر ، يتم وضع جزء من الوحدة في الرسم البياني الموجهة في EXE ويتم وضع الجزء الآخر في BPL. ولكن ما الذي يعتمد على الانقسام؟ هل يستند إلى شرط الاستخدامات ، أو بناءً على القائمة في "Build with Runtime Packages" هنا؟ مع استمرار الاختبار ، وجدت أنه إذا كانت القائمة تحتوي فقط على VCL60 ، فلا يزال يتم تحميل اثنين من BPL بالإضافة إلى One Exe في الذاكرة ؛ لقد تغير EXE: زاد عدد الوحدات الموجودة في الداخل ، وهي أساسًا في حزمة VCL60. أعتقد أنه يجب أن تكون هناك علاقة متطلبات بين حزم RTL و VCL. سيتم اختبار هذا في الخطوة التالية. ومع ذلك ، خلال عملية التقدير الأولية ، سيتم بالتأكيد استخدام قائمة الحزم لاستبعاد الوحدات الموجودة بالفعل في الحزمة من EXE.
بعد الاتصال الديناميكي ، هناك مشكلة أخرى: التحميل. هناك استراتيجيتان للتحميل ، والستاتيك ، والمعروف أيضًا باسم Automatic ، والذي ينشئ رمزًا من Delphi ، ويقوم بتحميل الحزمة تلقائيًا قبل تحميل EXE ؛ ذاكرة. المشكلة هي أنه يجب عليّ معرفة ما هي الظروف التي ستحملها دلفي تلقائيًا حزمة وتحت أي ظروف يمكنني تجنب أن تكون دلفي ذكية حتى أتمكن من استخدام الحزمة بمرونة. في التجربة السابقة ، لا يمكن ملاحظة إلا أنه قبل تنفيذ ملف DPR للبدء ، تم تحميل الحزمة المتصلة بشكل ثابت في الذاكرة. لا أعرف العملية المحددة.