kachwahed
07-11-2011, 02:40 PM
السلام عليكم ورحمة الله
Calling Conventions أو "اتفاقيات الاتصال" (الترجمة مباشرة وحرفية وقد لا توحي بالمقصود)
يقصد بها طريقة تمرير المعلمات (Parameters) إلى المناهج (Routine)
http://en.wikipedia.org/wiki/Calling_convention
وهي في إصدارات دلفي 32bit خمسة شهيرة: register, pascal, cdecl, stdcall, safecall
مثال تمرير باستخدام cdecl:
function MyFunction(X, Y: Real): Real; cdecl;
من ملفات الـ Help في دلفي نستخلص ما يلي:
تحدد طرق تمرير الملعمات (الباراميترات):
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
الآن شيء غريب!
أعتقد أن ترتيب تمرير المعلمات ينبغي أن يتم التفصيل فيه
صحيح إذا كتبنا:
function MyFunction(X, Y: Real): Real; register;
فإن تمرير المعلمات سيكون من اليسار إلى اليمين
أي: بدء بـ x ثم y وليس العكس
لكن هذا من حيث وصول القيم إلى MyFunction (أي دفعها إلى المكدس) ولكن ليس من حيث جلب قيم X و Y
يتضح ذلك إذا حاولنا مع دالتين تأتيان بقيمين X و Y
function MyFunction(getX(), getY(): Real): Real; register;
تخيل أن هناك أوامر تنفذ في getX() وgetY() أيهما سينفذ أولا!
الذي لاحظت أن جميع التوجهات يُؤتى بها من اليمين إلى اليسار (ما عدا pascal)
ثم توجه إلى المنهج كما هو مألوف
المثال في المرفق يوضح الفكرة.
إذا أخطأ في شيء فلا تترددوا بالتعقيب :)
Calling Conventions أو "اتفاقيات الاتصال" (الترجمة مباشرة وحرفية وقد لا توحي بالمقصود)
يقصد بها طريقة تمرير المعلمات (Parameters) إلى المناهج (Routine)
http://en.wikipedia.org/wiki/Calling_convention
وهي في إصدارات دلفي 32bit خمسة شهيرة: register, pascal, cdecl, stdcall, safecall
مثال تمرير باستخدام cdecl:
function MyFunction(X, Y: Real): Real; cdecl;
من ملفات الـ Help في دلفي نستخلص ما يلي:
تحدد طرق تمرير الملعمات (الباراميترات):
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
الآن شيء غريب!
أعتقد أن ترتيب تمرير المعلمات ينبغي أن يتم التفصيل فيه
صحيح إذا كتبنا:
function MyFunction(X, Y: Real): Real; register;
فإن تمرير المعلمات سيكون من اليسار إلى اليمين
أي: بدء بـ x ثم y وليس العكس
لكن هذا من حيث وصول القيم إلى MyFunction (أي دفعها إلى المكدس) ولكن ليس من حيث جلب قيم X و Y
يتضح ذلك إذا حاولنا مع دالتين تأتيان بقيمين X و Y
function MyFunction(getX(), getY(): Real): Real; register;
تخيل أن هناك أوامر تنفذ في getX() وgetY() أيهما سينفذ أولا!
الذي لاحظت أن جميع التوجهات يُؤتى بها من اليمين إلى اليسار (ما عدا pascal)
ثم توجه إلى المنهج كما هو مألوف
المثال في المرفق يوضح الفكرة.
إذا أخطأ في شيء فلا تترددوا بالتعقيب :)