سؤال

أنا أتعلم برمجة Win32 و WinMain النموذج الأولي يشبه:

int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )

لقد كنت في حيرة من أمري بشأن ما هذا WINAPI تم العثور على المعرف:

#define WINAPI      __stdcall

ماذا يفعل هذا؟أنا في حيرة من أمري بوجود شيء على الإطلاق بعد نوع الإرجاع.ما هو __stdcall ل؟ماذا يعني عندما يكون هناك شيء بين نوع الإرجاع واسم الوظيفة؟

هل كانت مفيدة؟

المحلول

__stdcall هو اصطلاح الاتصال المستخدم للوظيفة.يخبر هذا المترجم بالقواعد التي تنطبق على إعداد المكدس ودفع الوسائط والحصول على قيمة الإرجاع.

هناك عدد من اصطلاحات الاتصال الأخرى، __cdecl, __thiscall, __fastcall والمسمى الرائع __naked. __stdcall هو اصطلاح الاتصال القياسي لمكالمات نظام Win32.

تغطي ويكيبيديا تفاصيل.

يهم في المقام الأول عندما تقوم باستدعاء وظيفة خارج التعليمات البرمجية الخاصة بك (على سبيل المثال.واجهة برمجة تطبيقات نظام التشغيل) أو أن نظام التشغيل يتصل بك (كما هو الحال هنا مع WinMain).إذا كان المترجم لا يعرف اصطلاح الاستدعاء الصحيح، فمن المحتمل أن تحصل على أعطال غريبة جدًا حيث لن تتم إدارة المكدس بشكل صحيح.

نصائح أخرى

C أو C++ نفسها لا تحدد تلك المعرفات.إنها امتدادات للمترجم وتمثل اصطلاحات اتصال معينة.يحدد ذلك مكان وضع الوسائط، وبأي ترتيب، وأين ستجد الوظيفة المطلوبة عنوان المرسل، وما إلى ذلك.على سبيل المثال، __fastcall يعني أن وسيطات الوظائف يتم تمريرها عبر السجلات.

ال مقالة ويكيبيديا يقدم نظرة عامة على اصطلاحات الاتصال المختلفة الموجودة هناك.

لقد غطت الإجابات حتى الآن التفاصيل، ولكن إذا كنت لا تنوي الانتقال إلى التجميع، فكل ما عليك معرفته هو أنه يجب على كل من المتصل والمتصل به استخدام نفس اتفاقية الاتصال، وإلا فسوف تحصل على أخطاء من الصعب العثور عليها.

أوافق على أن جميع الإجابات حتى الآن صحيحة، ولكن هنا هو السبب.توفر برامج التحويل البرمجي C وC++ من Microsoft اصطلاحات استدعاء متنوعة للسرعة (المقصودة) لاستدعاءات الوظائف ضمن وظائف C وC++ الخاصة بالتطبيق.في كل حالة، يجب أن يتفق المتصل والمستدعى عليه على اتفاقية الاتصال التي سيتم استخدامها.الآن، يوفر Windows نفسه وظائف (واجهات برمجة التطبيقات)، وقد تم تجميعها بالفعل، لذا عند الاتصال بها، يجب عليك الالتزام بها.يجب أن تستخدم أي استدعاءات لواجهات برمجة تطبيقات Windows وعمليات الاسترجاعات من واجهات برمجة تطبيقات Windows اصطلاح __stdcall.

يتعلق الأمر بكيفية استدعاء الوظيفة - بشكل أساسي الترتيب الذي يتم به وضع الأشياء على المكدس ومن المسؤول عن التنظيف.

إليك الوثائق، لكنها لا تعني الكثير إلا إذا فهمت الجزء الأول:
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx

يتم استخدام __stdcall لوضع وسيطات الوظيفة في المكدس.بعد الانتهاء من الوظيفة، يقوم تلقائيًا بإلغاء تخصيص الذاكرة.يستخدم هذا للوسائط الثابتة.

void __stdcall fnname ( int, int* )
{
    ...
}

int main()
{
    CreateThread ( NULL, 0, fnname, int, int*...... )
}

هنا com.fnname لديه وسيطات تدفع مباشرة إلى المكدس.

لم أضطر إلى استخدام هذا من قبل حتى اليوم.هذا لأنني في الكود الخاص بي أستخدم خيوط المعالجة المتعددة وواجهة برمجة التطبيقات متعددة الخيوط التي أستخدمها هي Windows One (_beginthreadex).

لبدء الموضوع:

_beginthreadex(NULL, 0, ExecuteCommand, currCommand, 0, 0);

وظيفة تنفيذ الأمر يجب استخدم الكلمة الأساسية __stdcall في توقيع الطريقة حتى يتمكن beginthreadex من الاتصال بها:

unsigned int __stdcall Scene::ExecuteCommand(void* command)
{
    return system(static_cast<char*>(command));
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top