المدير AMINE PàTCHIKà
الجنس : تاريخ الميلاد : 25/01/1988 العمر : 36
المدير العام منتديات أمين عبلة الحب :
| موضوع: تحميل واستدعاء دوال وإجراءات DLL الخميس ديسمبر 27, 2012 3:13 pm | |
| تحميل واستدعاء دوال وإجراءات DLL
تحميل واستدعاء دوال وإجراءات DLL
مقدمة
بعيدا عن تعقيد الدرس السابق الذي يكفيك منه بشكل مبدئي أنك عرفت الشكل العام لوحدة DLL وعرفت كيف تنجزها ،لنبدأ في هذا الدرس معرفة النصف الثاني من القصة التي شرحنا في الدرس السابق نصفها الأول وهو إنجاز وحدة DLL ، هذا النصف الأخير هو كيفية استدعاء أو استيراد أو تحميل دوال وإجراءات DLL .
تحميل DLLs إلى تطبيقك :
قبل أن تتمكن من استخدام دالة أو إجراء موجود فى DLL فإنك بحاجة إلى تحميل DLL إلى الذاكرة ، تحميل DLL فى RunTime يمكن أن يكون بإحدى طريقتين :
1-التحميل الأستاتيكي Static Loading .
2-التحميل الديناميكي Dynamic Loading .
لكل من الطريقتين حسناتها وعيوبها ،لذا سأوضح الفرق بينهما :
1-التحميل الأستاتيكي:
يقصد به أن ال DLL سيُحمّل أوتوماتيكياً عندما يُنفّذ التطبيق الذي قام باستدعاء DLL ،ولاستخدام هذا النوع من الإستدعاء عليك أن تصرح عن الدالة أو الإجراء الموجود فى DLL باستخدام الكلمة المحجوزة External .
وطالما أن DLL قد حمل عند لحظة تحميل التطبيق بشكل أوتوماتيكي فكل ما عليك فعله لاستدعاء دالة أو إجراء موجود فى DLL هو استدعاء هذه الدالة أو الإجراء بشكل اعتيادي كما تستدعي أي دالة أو إجراء في Object Pascal .
حسنة هذا النوع من التحميل هي أنه الأسهل للوصول إلى دوال وإجراءات DLL ،وعيبه أن DLL يحمل فى لحظة تحميل البرنامج وبالتالى إذا احتوى DLL على عيوب ما فإن البرنامج سيواجه مشاكل في تحميله.
2-التحميل الديناميكي:
يقصد به أنك تستطيع تحميل DLL عندما تحتاج إليه وتوقف تحميله عندما لا تحتاج للتعامل معه كل ذلك أثناء حياة تطبيقك (وجوده بالذاكرة) .
لهذا النوع من التحميل ميزاته وعيبه ،الميزة الأولى هي أنك تستخدم الذاكرة عندما تحتاج إليها فقط ، أي أنك تستغل الذاكرة بفعالية أكبر ، الميزة الأخرى هي أن برنامجك سيحمل بشكل أسرع لأنه عند لحظة تحميل تطبيقك لن يحمل كل الكود الذي تحتاجه لتنفيذه (المقصود جزء DLL).
العيب الأساسي لاستخدام التحميل الديناميكي أنه يحتاج إلى عمل أكثر من جانبك.
أ-لتحميل DLL ديناميكيا عليك استخدام دالة Windows API التي تدعى Loadlibrary .
ب-عند انتهاء عملك مع DLL استخدم الدالة FreeLibrary لإلغاء تحميله من الذاكرة .
ج-استخدم الدالة GetprocAddress للحصول على مؤشر للدالة أو الإجراء الذي تحتاج لاستدعائه.
استدعاء الدوال والإجراءات الموجودة في DLLs :
كما قلنا سابقاً فإن الطريقة التي تستخدمها لاستدعاء دالة أو إجراء في DLL تعتمد على ما إذا كان DLL قد حمّل أستاتيكياً أم ديناميكياً .
أولاً الاستدعاء باستعمال التحميل الأستاتيكي :
لاستدعاء دالة أو إجراء ال DLL الذي حمل ستاتيكياً عملية بسيطة ، أولا التطبيق المستدعى يجب أن يحتوي على تصريح عن الدالة أو الإجراء ،بعد ذلك يمكنك استدعاء الدالة أو الإجراء كما تفعل عادةً في Object Pascal .
لاستيراد دالة أو إجراء محتوى في DLL استخدم الكلمة المفتاحية External في تصريح الدالة أو الإجراء ،كمثال لنأخذ الإجراء SayHell الذي رأيناه سابقاً ،التصريح عنه فى التطبيق المستدعى يكون كالتالي:
Externalتخبر المترجم أن الإجراء يمكن أن يكون فى (فى حالتنا هذه) ، الاستدعاء الفعلي للإجراء( وهو الخطوة التالية وحيثما احتجت إليه) لا يظهر أي اختلاف عن أي إجراء آخرSayHello(Self);بالطبع فإن جملة التصريح عن الإجراء أو الدالة يجب أن تكون مطابقة للشكل الذي ظهر به فىObject Pascalبحالة الحروف كبيرة أم صغيرة ،فإن أي خطأ تقع فيه في تهجئة أو شكل الحروف فى إسم الدالة أو الإجراء أثناء تصريحك عنه سيؤدي إلى اعتراض فىاستخدام الكلمة المحجوزة :هذه الكلمة تملك ثلاث حالات لاستيراد إجراء أو دالة من : :في هذه الطريقة يمكنك أن تصرح عن إسم الدالة أو الإجراء بالضبط كما جاء في :'; :فى هذه الطريقة عليك أن تعين قيمة لترتيب الدالة أو الإجراء كما صدّر من:; ;فى هذا المثال قمت باستيراد الإجراء الذي صدر منindex 99،أستطيع تسمية الإجراء أي إسم أريده فى التطبيق المستدعي ،وسيكون المقصود هو ذلك الإجراء فىindex . :تسمح لي هذه الطريقة بأن أستورد الإجراء بواسطة اسمه الأصلي ،لكن أعطي الإجراء اسما جديداً فى التطبيق المستدعي ، وهذا مشابه للتالي :; ';هنا استوردت الإجراء المدعوCoolProcedureملاحظةDLLثانياً استدعاء الدوال والإجراءات باستخدام التحميل الديناميكي :إن استدعاء الدوال والإجراءات المحملة ديناميكياً يتطلب منك أن تعرف مؤشر للإجراء أو الدالة الموجودة فى (سبق وقدمت شرحا لموضوع مؤشر إجراء أو دالة في الدرس السابق) ،لشرح هذا الموضوع لنفترض أنك تملك إجراء فيSayHelloوهو يمكن أن يظهر كالتالي :begin `DLL Message Box', MB_OK or MB_ICONEXCLAMATION);typeDLLواستخدام الدالة أو الإجراء ثم إلغاء تحميله عند انتهاء العمل معه (استخدم الدوال المذكورة فى بداية هذا الدرس لتحقيق ذلك)var SayHello : TSayHello; { Load the DLL. } { Get the address of the procedure. } { Call the procedure. } { Unload the DLL. }end;من الأفضل أن تستخدمLoadLibraryفي التقاط ممسك ملفGetprocAddressفى التقاط عنوان الإجراء أو الدالة ، فتلافيا لتوقف البرنامج عند حدوث ذلك نضيف هذا الفحص :typevar SayHello : TSayHello; DLLInstance := LoadLibrary(`testdll.dll'); MessageDlg(`Unable to load DLL.', mtError, [mbOK], 0); end; if @SayHello <> nil then else FreeLibrary(DLLInstance);DLL[/b]باستخدام مخزن الأغراضDLLفي دلفي اتبع الخطوات التالية :FileNewلعرضprocedure MyProcedure(var S : string); { Procedure code here. }: begin code here. }library TestDLL; SysUtils, Forms,procedure SayHello(AForm : TForm); MessageBox(AForm.Handle, `Hello From a DLL!',end;begin `DLL Message Box', MB_OK or MB_ICONEXCLAMATION);procedure DoSomethingReallyCool; MessageBox(0, `Something really cool.',end; SayHello, DoSomethingReallyCool;endlibrary TestDLL; SysUtils, Forms,procedure MyDLLProc(Reason: Integer); if Reason = DLL_PROCESS_DETACH then MessageBox(0, `DLL is unloading!',end;begin `This DLL was loaded dynamically',end; SayHelloDyn; DLLProc := @MyDLLProc;. [b]CallDllU.pas.
interface Windows, Messages, SysUtils, Classes, Graphics, type HelloBtn: TButton; DynamicLoadBtn: TButton; procedure HelloBtnClick(Sender: TObject); procedure DynamicLoadBtnClick(Sender: TObject); private public end; Form1: TForm1; procedure imported by name. } external `testdll.dll'; procedure imported by ordinal. } external `testdll.dll' index 99; procedure imported and renamed. } external `testdll.dll' name `DoSomethingReallyCool';{$R *.DFM}beginend;beginend;beginend;typevar SayHello : TSayHello; { Load the DLL. } { If loading fails then bail out. } MessageDlg(`Unable to load DLL.', mtError, [mbOK], 0); end; @SayHello := GetProcAddress(DLLInstance, `SayHelloDyn'); if @SayHello <> nil then else { Unload the DLL. }end;.
الخلاصة:
رأينا في هذا الدرس كيف نحمل وحدة DLL ثم كيف نستدعي دالة أو إجراء من DLL واتجهنا إلى التطبيق العملي لإيضاح بناء واستدعاء DLL .
إلى هنا نكون قد غطينا الجزء الأكبر من دراستنا لل DLL حيث أننا أصبحن قادرين على إنشائه والتعامل معه. ....والله الموفق .... ( ص . ع )
تحياتي لكم
| |
|