1. ابدأ أول مشروع DLL الخاص بك
1.file-> أغلق All-> file-> جديد [dll >
شفرة : |
// إنشاء رمز تلقائيًا على النحو التالي Library Project2 ؛ // هذا هراء. يستخدم sysutils ، الطبقات {$ r *.res} يبدأ نهاية. |
2. أضف func للدخول:
شفرة : |
Library Project2 ؛ يستخدم sysutils ، الطبقات وظيفة mymax (x ، y: integer): integer ؛ يبدأ إذا كان x> y ثم النتائج: = x آخر النتائج: = y ؛ نهاية ؛ // تذكر: اسم المكتبة لا يهم ، لكن حالة DLL-Func مرتبطة. // كتابة mymax في dll-func-name تختلف عن mymax. إذا كان مكتوبًا بشكل خاطئ ، على الفور // والنتيجة هي أنك تسأل أنه لا يمكن فتح AP التي تستخدم DLL على الإطلاق. // الحالة العلوية والسفلية للمعلمات على ما يرام. لا يجب أن يكون لها نفس الاسم. إذا كان النموذج الأولي (x ، y: integer) // اكتبها كـ (A ، B: Integer) في الوقت المناسب ، هذا جيد. // تذكر: إضافة stdcall آخر. يقول الكتاب أنه إذا كنت تكتب DLLs باستخدام Delphi ، وآمل ليس فقط // إذا كانت Delphi-AP تأمل أيضًا في استخدام BCB/VC-AP ، وما إلى ذلك ، فمن الأفضل إضافة stdcall ؛ // نمط المعلمة: لدى Delphi العديد من الأنماط المتغيرة ، والتي لا تشبه DLL بالطبع // ، يجب أن تكون اللغة الأصلية لنظام التشغيل Windows/DLL C. لذلك إذا كنا نريد أن نمر وإخراج معلمات DLL ، فنحن نحن // استخدم أكبر قدر ممكن وفقًا للقواعد. إذا كتبت هذين ، فإن الأخير سيكون مشكلة كبيرة. إذا لم تكن على دراية بـ C // إذا كان هذا على ما يرام. سنتحدث عنها لاحقًا. {$ r *.res} يبدأ نهاية. |
3. أرسل هذه الفانكات القابلة للمشاركة من DLL ودع العالم الخارجي (إنه Delphi-ap) يستخدم: Guangru
لذلك ، لا يمكن لـ AP الخاص بك استخدامها ، فأنت بحاجة إلى إضافة صادرات.
شفرة : |
{$ r *.res} صادرات mymax يبدأ نهاية. |
4. حسنًا ، يمكنك الضغط على CTRL-F9 للتجميع. لا تضغط على F9 في هذا الوقت. DLL ليس exe┌ الذي لا يمكن تنفيذه بشكل منفصل. إذا كان لدى DLL خطأ في هذا الوقت ، فيرجى تصحيحه. اضغط CTRL-F9 مرة أخرى. قد يكون هناك تحذير في هذا الوقت ، لا يهم ، فقط دراسته وألقي نظرة. اضغط على Ctrl-F9 مرة أخرى ، ثم "تم التجميع". سيكون هناك *.dll في نفس الدليل. تهانينا ، يتم الانتهاء من المهمة.
2. إجراء اختبار: افتح تطبيقًا جديدًا:
1. أضف tbutton
شفرة : |
ShowMessage (inttostr (mymax (30،50))) ؛ |
2. أخبر Exe بالذهاب إلى هناك للقبض على Func
شفرة : |
// إضافة إلى النموذج ، واجهة ، var وظيفة mymax (x ، y: integer): integer ؛ // mytestdll.dll يكتب اسم مشروع DLL لك من قبل // لا يهم إذا كان اسم DLL أعلى وأقل. ولكن تذكر أن تضيف تمديد. dll. على Win95 أو NT ، // ليست هناك حاجة لإضافة تمديد ، ولكن قد يكون هذان OSS أقل وأقل. تحتاج إلى إضافة تمديد. |
حسنًا ، الأمر بسيط.
هل المثال أعلاه بسيط للغاية؟ يمكن للأصدقاء الذين يعرفون Delphi أن يروا أن الكود أعلاه هو نفسه في الأساس كتابة برنامج Delphi العام ، باستثناء أن هناك معلمة stdcall إضافية بعد وظيفة TestDll ويتم الإعلان عن وظيفة TestDll باستخدام عبارة Exports. فقط قم بتجميع الكود أعلاه ويمكنك الحصول على مكتبة ارتباط ديناميكية تسمى Delphi.dll. الآن ، دعنا نرى ما يحتاج إلى الاهتمام. 1. يجب إضافة جميع الوظائف أو الإجراءات المكتوبة في DLL باستخدام معلمات استدعاء STDCALL. في بيئة Delphi 1 أو Delphi 2 ، تكون معلمة الاتصال بعيدة. بعد Delphi 3 ، تم تغيير هذه المعلمة إلى STDCALL ، بهدف استخدام تقنية نقل المعلمة Win32 القياسية بدلاً من معلمات التسجيل المحسنة. نسيت استخدام معلمة STDCALL خطأ شائع. والسبب هو أن معلمة التسجيل هي المعلمة الافتراضية لـ Delphi.
2. يجب الإعلان عن الوظائف والإجراءات المكتوبة كوظائف خارجية باستخدام عبارة الصادرات.
كما ترون ، يتم الإعلان عن وظيفة testDll كدالة خارجية. هذا يسمح لمشاهدة الوظيفة خارجيًا. (إذا لم يكن هناك خيار عرض سريع ، فيمكنك تثبيته من قرص Windows.) تظهر وظيفة TestDll في شريط جدول التصدير. سبب وجيه آخر هو أننا إذا لم نعلن بهذه الطريقة ، فلن يتم استدعاء الوظائف التي نكتبها ، وهذا شيء لا يريد أحد رؤيته.
3. عند استخدام معلمات نوع السلسلة الطويلة والمتغيرات ، يجب الرجوع إلى حارم.
نوع السلسلة في دلفي قوي للغاية. (نعم ، لقد قرأته بشكل صحيح ، إنه في الواقع ميغابايتان.) في هذا الوقت ، إذا أصرت على استخدام معلمة نوع السلسلة ، المتغير أو حتى التسجيل ، يجب أن تشير إلى وحدة الحواجز ، ويجب أن تكون المرجع الأول . إنها أول وحدة مرجعية بعد بيان الاستخدامات. كما هو موضح في المثال التالي:
يستخدم
حليمة ،
sysutils ،
الطبقات
نقطة أخرى هي أن نفس الشيء يجب القيام به في ملف المشروع (*.dpr) بدلاً من ملف الوحدة (*.Pas). إذا لم تفعل هذا ، فمن المحتمل أن تدفع حادث تحطم. طريقة تجنب استخدام نوع السلسلة هي إعلان المعلمات والمتغيرات ، وما إلى ذلك من نوع السلسلة مثل نوع PCHAR أو ShortString (مثل: S: String [10]). تحدث نفس المشكلة عند استخدام المصفوفات الديناميكية ، كما هو موضح أعلاه.
الفصل 3: دعوة ثابتة إلى DLL TOP في Delphi
استدعاء DLL أسهل من كتابة DLL. أولاً ، سأقدم طريقة الاتصال الثابتة لك. وبالمثل ، دعنا أولاً نعطي مثالًا على المكالمات الثابتة.
الوحدة 1 ؛
واجهة
يستخدم
Windows ، الرسائل ، sysutils ، الفئات ، الرسومات ،
عناصر التحكم ، النماذج ، الحوار ، stdctrls ؛
يكتب
tform1 = فئة (tform)
EDIT1: TEDIT ؛
Button1: Tbutton ؛
الإجراءات button1click (المرسل: tobject) ؛
خاص
{إعلانات خاصة}
عام
{الإعلانات العامة}
نهاية؛
var
Form1: Tform1 ؛
تطبيق
{$ r *.dfm}
// الكود التالي في هذا السطر هو الرمز الذي كتبناه حقًا
وظيفة testDll (i: integer): integer ؛ stdcall ؛
خارجي "delphi.dll" ؛
الإجراء tform1.button1click (المرسل: tobject) ؛
يبدأ
edit1.text: = inttoStr (testDll (1)) ؛
نهاية؛
نهاية.
في المثال أعلاه ، وضعنا مربع تحرير (تحرير) وزر في النموذج ، وكتبنا رمزًا صغيرًا جدًا لاختبار Delphi.dll الذي كتبناه للتو. يمكنك أن ترى أن المهمة الوحيدة التي نقوم بها هي وضع جزء الوصف من وظيفة TestDLL في التنفيذ وتحديد موقع delphi.dll مع البيان الخارجي. (في هذا المثال ، يوجد برنامج الاتصال و Delphi.dll في نفس الدليل.) من المثير أن وظيفة TestDll التي كتبناها قد تم التعرف عليها بسرعة من قبل Delphi. يمكنك إجراء تجربة مثل هذه: أدخل "TestDll (" ، وسرعان ما ستستخدم Delphi شريط مطالبة الطيران للمطالبة بك المعلمات التي يجب أن تدخلها ، تمامًا مثل استخدام وظائف أخرى محددة في Delphi.
التالي:
1. استخدم STDCALL لاستدعاء المعلمات.
كما ذكر أعلاه ، عند الإشارة إلى الوظائف والإجراءات في DLL ، يجب عليك أيضًا استخدام معلمة STDCALL ، لنفس السبب المذكور أعلاه.
2. استخدم العبارة الخارجية لتحديد مسار واسم ملف DLL المسمى.
كما ترون ، نحدد اسم ملف DLL ليتم استدعاؤه في العبارة الخارجية. لا يوجد مسار كتابة لأن ملف DLL والبرنامج الرئيسي الذي يطلق عليه في نفس الدليل. إذا كان ملف DLL في C:/، فيمكننا كتابة العبارة المرجعية أعلاه على أنها "C: /Delphi.dll" الخارجية. لاحظ أنه يجب كتابة لاحقة الملف.
3. لا يمكن استدعاء المتغيرات العالمية من DLL.
إذا أعلننا نوعًا من المتغيرات العالمية في DLL ، مثل: var s: byte. وبهذه الطريقة ، يمكن استخدام المتغير العالمي بشكل طبيعي في DLL ، ولكن لا يمكن استخدام S بواسطة برنامج الاتصال ، ولا يمكن تمرير S كمتغير عالمي لبرنامج الاتصال. ومع ذلك ، يمكن تمرير المتغيرات المعلنة في برنامج الاتصال كمعلمات إلى DLL.
4. يجب أن يكون DLL المسمى.
هذا أمر مهم. إذا لم يكن المسار المحدد واسم الملف موجودًا أو أن المسار واسم الملف المحدد غير صحيح ، فسيطلب النظام "حدث خطأ أثناء بدء البرنامج" أو "لم يتم العثور على ملف *.DLL" عند تشغيل البرنامج الرئيسي.
الفصل 4 استدعاء DLL TOP ديناميكي في Delphi
استدعاء DLLs ديناميكيا معقد نسبيا ، ولكن مرنة للغاية. لتوضيح المشكلة بدقة ، نقدم هذه المرة مثالًا على استدعاء DLL مكتوب في C ++. أولاً ، قم بتجميع برنامج مصدر DLL التالي في C ++.
#يشمل
extern "C" _declspec (dllexport)
int winapi testc (int i)
{
العودة أنا.
}
بعد التجميع ، يتم إنشاء ملف DLL. من أجل الراحة ، ما زلنا نشير إلى برنامج الاتصال أعلاه ، ولكن استبدل البيان الأصلي في عملية Button1Click بالرمز التالي.
الإجراء tform1.button1click (المرسل: tobject) ؛
يكتب
tintfunc = function (i: integer): integer ؛ stdcall ؛
var
Th: Thandle ؛
TF: Tintfunc ؛
TP: Tfarproc ؛
يبدأ
Th: = loadlibrary ('cpp.dll') ؛
إذا th> 0 ثم
يحاول
TP: = getProcaddress (th ، pchar ('testc')) ؛
إذا tp <> nil
ثم ابدأ
tf: = tintfunc (tp) ؛
edit1.text: = inttoStr (tf (1)) ؛
نهاية
آخر
ShowMessage ("وظيفة Testc غير موجودة") ؛
أخيراً
freelibrary (th) ؛
نهاية
آخر
ShowMessage ('cpp.dll غير موجود') ؛
نهاية؛
كما رأيت ، فإن تقنية الاتصال الديناميكية هذه معقدة للغاية ، ولكن طالما قمت بتعديل المعلمات ، مثل تعديل اسم DLL في التحميل ("cpp.dll") لتكون "delphi.dll" ، يمكنك تغيير ديناميكيًا دعا DLL.
1. تحديد نوع الوظيفة أو الإجراء المراد استدعاؤه.
في الكود أعلاه ، نحدد نوع Tintfunc ، والذي يتوافق مع وظيفة Testc التي سنقوم بالاتصال بها. يجب إجراء نفس التعريف في المكالمات الأخرى. وأضف أيضًا معلمات استدعاء stdcall.
2. إطلاق DLL.
أطلقنا على DLL ديناميكيًا باستخدام LoadLibrary ، لكن تذكر أنه يجب عليك إطلاق DLL يدويًا باستخدام مكتبة الأداء بعد الاستخدام ، وإلا فإن DLL ستأخذ الذاكرة حتى يمكنك الخروج من النوافذ أو إيقاف تشغيلها.
الآن دعونا نقيم مزايا وعيوب طريقتي الاتصال DLL. الطريقة الثابتة سهلة التنفيذ وسهلة الإتقان وأسرع بشكل عام ، وهي أكثر أمانًا وأكثر موثوقية ؛ لتشغيله حتى يتم إصدار DLL فقط في نهاية البرنامج ، ويمكن للأنظمة القائمة على المترجمات مثل Delphi استخدام هذه الطريقة. الطرق الديناميكية تحل أوجه القصور بشكل أفضل في الطرق الثابتة ، ويمكنها بسهولة الوصول إلى وظائف وإجراءات DLL ، وحتى الوظائف أو الإجراءات المضافة حديثًا في بعض الإصدارات القديمة تحتاج الوظيفة أو الإجراء إلى تحديد العديد من الأنواع المعقدة وطرق الاتصال. بالنسبة للمبتدئين ، يوصي المؤلف باستخدام طرق ثابتة ثم استخدام طرق الاتصال الديناميكية بعد أن تكون كفاءة.
الفصل 5 نصائح عملية لاستخدام أعلى DLL
1. مهارات الكتابة.
1. من أجل ضمان صحة DLL ، يمكنك أولاً كتابته كجزء من تطبيق عادي ، وتصحيحه بشكل صحيح ، ثم فصله عن البرنامج الرئيسي وتجميعه في DLL.
2. من أجل ضمان عالمية DLL ، يجب أن تمنع أسماء عناصر التحكم المرئية من الظهور في DLL ، مثل: edit1 name في text1.tex ؛ بعض السجلات.
3. لتسهيل تصحيح الأخطاء ، يجب أن تكون كل وظيفة وعملية قصيرة وموجزة قدر الإمكان ، وينبغي أن تكون مصحوبة بتعليقات محددة ومفصلة.
4. يجب استخدام المحاولة للتعامل مع الأخطاء والاستثناءات المحتملة.
5. الرجوع إلى أقل عدد ممكن من الوحدات لتقليل حجم DLL ، خاصة لا تشير إلى الوحدات المرئية ، مثل وحدات الحوار. على سبيل المثال ، بشكل عام ، لا يمكننا الرجوع إلى وحدات الفئات ، والتي يمكن أن تقلل من DLL المترجمة بحوالي 16 كيلو بايت.
2. المهارات الاتصال.
1. عند استخدام طرق ثابتة ، يمكنك إعادة تسمية الوظيفة أو الإجراء المدعو. في مثال DLL المكتوبة في C ++ المذكورة أعلاه ، إذا تمت إزالة عبارة "C" الخارجية ، فسيقوم C ++ بتجميع بعض أسماء الوظائف الغريبة ، وسيتم تسمية وظيفة Testc الأصلية @Testc $ S وغيرها من الأسماء الغريبة المضحكة. يستخدم C ++ Name Millgling Technology. اسم الوظيفة هذا غير قانوني في دلفي ، يمكننا حل هذه المشكلة مثل هذه:
أعد كتابة الوظيفة المرجعية كـ
وظيفة testc (i: integer): integer ؛ stdcall ؛
خارجي 'cpp.dll' ؛ name '@testc $ s' ؛
وظيفة الاسم هي إعادة تسمية.
2. يمكنك وضع DLLs التي كتبناها في دليل Windows أو دليل Windows/System. القيام بذلك يمكن أن يكتب اسم DLL فقط دون كتابة المسار في العبارة الخارجية أو في عبارة LoadLibrary. لكن من غير المناسب القيام بذلك. ضع DLLs التي كتبتها في دليل النظام!
3. تصحيح المهارات.
1. نعلم أنه لا يمكن تشغيل DLL وتصحيح أخطاء خطوة بخطوة عند الكتابة. هناك طريقة للقيام بذلك ، أي إعداد برنامج مضيف في قائمة Run | Parameters. أضف اسم البرنامج المضيف إلى شريط التطبيق المضيف للصفحة المحلية لأداء تصحيح الأخطاء خطوة بخطوة ومراقبة نقطة التوقف وتشغيله.
2. إضافة معلومات إصدار DLL. ذكرت الملاحظات الافتتاحية أن معلومات الإصدار مهمة للغاية بالنسبة إلى DLLs. يجدر إضافة مثل هذه المساحة الصغيرة. لسوء الحظ ، لا يمكن استخدام خيار الإصدار في Project | Options مباشرة. كما هو موضح في المثال التالي:
مكتبة دلفي
يستخدم
sysutils ،
الطبقات
{$ r *.res}
// لاحظ أنه يجب إضافة سطر الرمز أعلاه في هذا الموضع
وظيفة testDll (i: integer): integer ؛ stdcall ؛
يبدأ
النتائج: = i ؛
نهاية؛
صادرات
testdll
يبدأ
نهاية.
3. من أجل تجنب تكرار الأسماء مع DLLs الأخرى ، من الأفضل استخدام مزيج من الأحرف والأرقام والرسومات السفلية عند تسمية DLLs التي تكتبها. على سبيل المثال: jl_try16.dll.
4. إذا كنت قد قمت بالفعل بتجميع بعض DLLs في Delphi 1 أو Delphi 2 ، فإن DLL الذي قمت بتجميعه هو 16 بت. ما عليك سوى إعادة ترجمة الكود المصدري في بيئة New Delphi 3 أو Delphi 4 ويمكنك الحصول على DLL 32 بت.
[بعد ملاحظة]: بالإضافة إلى الطرق الأكثر شيوعًا لاستخدام DLLs المقدمة أعلاه ، يمكن أيضًا استخدام DLLs كحاملات موارد. على سبيل المثال ، فإن تغيير الرموز في Windows هو المورد في DLL المستخدم. بالإضافة إلى ذلك ، فإن تقنية تصميم DLL التي تتقنها لديها العديد من الفوائد لاستخدام برمجة OLE و COM و ActiveX أكثر تقدمًا.