![]() |
|
اتفاقيات الاستدعاء Calling Conventions مع المناهج - نسخة قابلة للطباعة +- delphi4arab منتديات دلفي للعرب (https://delphi4arab.net/forum) +-- قسم : منتديات دلفي التقنية (https://delphi4arab.net/forum/forumdisplay.php?fid=6) +--- قسم : دلفي والتعامل مع النظام و الذاكرة (https://delphi4arab.net/forum/forumdisplay.php?fid=20) +--- الموضوع : اتفاقيات الاستدعاء Calling Conventions مع المناهج (/showthread.php?tid=3574) |
اتفاقيات الاستدعاء Calling Conventions مع المناهج - kachwahed - 07-11-2011 السلام عليكم ورحمة الله Calling Conventions أو "اتفاقيات الاستدعاء" (الترجمة مباشرة وحرفية وقد لا توحي بالمقصود) يقصد بها طريقة تمرير المعلمات (Parameters) إلى المناهج (Routine) كود : http://en.wikipedia.org/wiki/Calling_conventionمثال تمرير باستخدام cdecl: كود : function MyFunction(X, Y: Real): Real; [color=Blue]cdecl[/color];تحدد طرق تمرير الملعمات (الباراميترات): 1- ترتيب إرسال القيم (من اليمين إلى اليسار أو العكس) 2- إزالة (أو عدم إزالة) المغيرات من المكدس (Stack) بعد الخروج من المنهج 3- طريقة التعامل مع الاستثناءات وإصدار رسائل الأخطاء Exception 4- موضع تخزين المعلمات (في المكدس أو في سجلات الـ CPU) التوجيه الافتراضي في دلفي هو register، إذا لم تكتب أي شيء فكأنك كتبت register بعد اسم المنهج. التوجيه، ترتيب الإرسال، المسؤول عن حذف المتغيرات، موضع التخزين register ، من اليسار إلى اليمين، المنهج نفسه، السجلات pascal، من اليسار إلى اليمين، المنهج نفسه، المكدس cdecl، من اليمين إلى اليسار، مستدعي المنهج، المكدس stdcall، من اليمين إلى اليسار، المنهج نفسه، المكدس safecall، من اليمين إلى اليسار، المنهج نفسه، المكدس ملاحظات: - يستخدم التوجيه register حتى ثلاث سجلات لتخزين المعلمات، وهو أسرع عند التنفيذ طبعا - التوجيه safecall يستخدم لتوجيه رسائل الاستثناءات، في بيئة Windows يتم إشعار واجهات COM (التي تورث من IDispatch) لإثارة الاستثناءات - عند التعامل مع API يستخدم عادة stdcall أو safecall - توجيه pascal لا زال فعال لأغراض التوافقية (Compatibility)، في حين التوجيهات near و far و export لم تعد تعمل وتركت لنفس السبب (مخصصة لبيئة 16 bit). انتهى. Peter Below يشرح بشكل مماثل (بمثال) نفس الفكرة: كود : http://www.swissdelphicenter.ch/torry/showcode.php?id=1233الآن شيء غريب! أعتقد أن ترتيب تمرير المعلمات ينبغي أن يتم التفصيل فيه صحيح إذا كتبنا: PHP كود : function MyFunction(X, Y: Real): Real; register; أي: بدء بـ x ثم y وليس العكس لكن هذا من حيث وصول القيم إلى MyFunction (أي دفعها إلى المكدس) ولكن ليس من حيث جلب قيم X و Y يتضح ذلك إذا حاولنا مع دالتين تأتيان بقيمين X و Y PHP كود : function MyFunction(getX(), getY(): Real): Real; register; الذي لاحظت أن جميع التوجهات يُؤتى بها من اليمين إلى اليسار (ما عدا pascal) ثم توجه إلى المنهج كما هو مألوف المثال في المرفق يوضح الفكرة. إذا أخطأ في شيء فلا تترددوا بالتعقيب
اتفاقيات الاستدعاء Calling Conventions مع المناهج - mobile - 07-11-2011 بارك الله فيك مشرفنا الغالي كنت بصدد كتابة طلب شرح لمثل هذا الموضوع اي انواع الاتصلات واستحييت لكثرة طلباتي وعدم تقديم اي شيئ للاخوة في هذا المنتدى الغالي هذا كان بسبب مشكلة حصلت لي في برنامجي الذي يتصل بمكتبة ديناميكية فيها عنصر edit ياتي هذا الفورم فوق الساعة لاكتب فيه ما **** ان ابحث عنه فيرسل للبرنامج كلمة البحث عن طريق stdcall لكن بعد عدة مرات او عندما اترك البرنامج لمدة لا ابحث فيه . ثم اعيد كتابة كلمة البحث تواجهني رسالة خطا فشككت في طريقة الربط اي بين المكتبة الديناميكية والبرنامج علما اني اعيد تشغيل البرنامج فيشتغل عادي وبعد مدة زمنية لا يعمل هل تظن ان stdcall هي السبب ؟ اتفاقيات الاستدعاء Calling Conventions مع المناهج - hanipino - 07-11-2011 و عليكم السلام و رحمة الله . الاخ كاش واحد , على حسب ما فهمت ان التوجيه register يعمل على تخزين 3 (الثلاث) متغيرات الاولى فى المسجلات بالترتيب التالى : المتغير الاول فى EAX المتغير الثانى فى EDX المتغير الثالث فى ECX اما باقى المتغيرات هى التى تدفع الى المكدس من اليسار الى اليمين . كمثال .. الاجراء DefaultCall يصبح بهذا الشكل كود : procedure DefaultCall(EAX, EDX, ECX, O, T: Integer);register; // = register; Right to Left <---
begin
end;كود : DefaultCall(1, 2, 3, getOne, getTwo);شكرا و بالتوفيق . اتفاقيات الاستدعاء Calling Conventions مع المناهج - kachwahed - 07-11-2011 إقتباس :هل تظن ان stdcall هي السبب ؟لا أظن ذلك... أعتقد أن الخطأ في اختيار طريقة التمرير الأحسن يسبب نتائج غير متوقعة أو خاطئة ولا يتسبب في الغالب في أخطاء... أيضا التمرير بـ stdcall هو الأنسب في Win32 لأن الويندوز نفسه يستخدم هذا التمرير. إقتباس :التى تدفع الى المكدس من اليسار الى اليمين .بالضبط! كذلك تدفع إلى المكدس، وهذا هو المتفق عليه غير أن الإتيان بها (أي البحث عن القيم التي ستخزن في السجلات eax, ebx, ecx) ولا أقصد تخزينها، يكون حسب ما لاحظت من اليمين إلى اليسار أي هنا: كود : DefaultCall(1, 2, 3, getOne, getTwo);لاحظ المثال: PHP كود : {$APPTYPE CONSOLE}كيف تفسر النتائج؟ اتفاقيات الاستدعاء Calling Conventions مع المناهج - mobile - 08-11-2011 هذه هي الرسالة التي يصدرها بعد حوالي 6 دقائق من العمل بالبرنامج Access violation at address 02DB66CC. Read of address 02DB66CC. وهذه هي العملية التي يبعثها dll الى البرنامج procedure sendtex(stext:ShortString) ;stdcall;external '.\GSmob.exe' اتفاقيات الاستدعاء Calling Conventions مع المناهج - hanipino - 08-11-2011 نعم اخ كاش واحد اذا كان الاجراء ذو التوجيه register و يحتوى على ثلاث متغيرات او اقل فلا يهم الاتجاه الذى ياتى بهم (مع انه من اليمين الى ليسار) المهم السجلات التى ستحفض تلك القيم . بعد الثلاث متغيرات الاولى سيدفع ل المكدس من اليسار الى اليمين . اى الشىء المهم فى الاتجاه هو عند الدفع الى المكدس و الله اعلم . مثلا كل التوجيهات الاخرى pascal, cdecl ... الخ تعمل على دفع المتغيرات الى المكدس باتجاه معين دون تخزين اى شىء فى المسجل عكس التوجيه register ( حتى اسمه يدل عليه) هذا التوجيه يخزن 3 متغيرات الاولى فى المسجلات . و بعد الثلاث متغيرات هاته تاتى اهمية الاتجاه لانه سيدفعها الى المكدس .
اتفاقيات الاستدعاء Calling Conventions مع المناهج - me_delphi - 08-11-2011 و عليكم السلام و رحمة الله وبركاته إقتباس :stdcall، من اليمين إلى اليسار، المنهج نفسه، المكدس اغلب دوال API مكتوبة بلغة C وتعتمد على هدا النوع من Calling ولهدا يتم دفع البارمترات في المكدس بشكل معكوس و لنزيد الأمر أكثر وضوحا هدا مثال لدالة يعرفها الجميع MessageBoxA Delphi+ASM PHP كود : procedure TForm1.FormCreate(Sender: TObject);أنظر كيف تم دفع البارمترات البارمتر الأول مقبض النافدة هو آخر ماتم دفعه للمكدس (push 0 //handle) اتفاقيات الاستدعاء Calling Conventions مع المناهج - kachwahed - 14-11-2011 ملاحظة: التوجيه forward يستخدم لأجل تعريف لاحق في قسم implementation (لأن ذلك غير ممكن فرضا) مثال: كود : var
b: bool = false;
implementation
procedure test; [color=Red]forward[/color];
procedure callTest();
begin
if b then
test;
end;
procedure test();
begin
callTest;
b := false;
end;قد تجد في بعض المناهج عبارة nil = وهي فقط من أجل تهيئة متغيرات المناهج بقيمة افتراضية: PHP كود : varPHP كود : p: procedure; stdcall = nil; اتفاقيات الاستدعاء Calling Conventions مع المناهج - kachwahed - 09-03-2012 التوجيهان assembler وinline ما تركا إلا لأغراض التوافق مع الإصدارات القديمة ويتم إلغاؤها عند التجميع (ِCompile)، هكذا جاء في Help دلفي 7... غير أن كتابة التوجيه inline يعد خطء نحوي، رغم وجوده حتى قبل إصدارات دلفي 2005! والدليل أن الكلمة محجوزة ولونها مغاير: كود : [color=blue]inline[/color][color=Black]: char;[/color] //< -- [color=Red]ERROR[/color]ويظن أنها بقيت inline لاستعمال لاحق (دلفي 2005 فما فوق) ترتيب الارسال عند assembler من اليمين إلى اليسار PHP كود : procedure AssemblerCall(i, j: Integer); assembler// Right to Left <--- |