سؤال

على حد علمي ، يمكن فقط لاتفاقية مكاسب المتصل التي يمكنها استخدام وسيطات متغيرة.
بالمناسبة ، يتم الإعلان عن Winapi StringCchprintfw مثل هذا. (أزلت SAL)

__inline hresult __stdcall
StringCchprintfw (
strsafe_lpwstr pszdest ، size_t cchdest ، strsafe_lpcwstr pszformat ، ...
);

هل يمكن أن يكون لدى stdcall حجج متغيرة أيضًا؟

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

المحلول

رقم stdcall استدعاء الاتفاقية لديها Callee تنظيف المكدس. نظرًا لأن Callee تقوم بتنظيف المكدس ، فلا توجد طريقة لتعرفها في وقت الترجمة المبلغ الذي يجب إيقافه ، وبالتالي لا يمكن أن يكون له وسيط متغير.

من أجل الحصول على عدد متغير من وسيطات الوظائف التي تحتاج إلى استخدامها CDECL, الذي لديه المتصل تنظيف المكدس. هذا كل المترجم لتحديد عدد الوسائط التي يتم تمريرها ، وبما أن المتصل يقوم بتنظيف المكدس ، فإنه يعرف أيضًا مقدار ما يجب إخراج المكدس عند إرجاع المكالمة إلى الوظيفة.

في الحالة المذكورة أعلاه ، يتم الإعلان عن الوظيفة لاستخدامها __stdcall, ، كما ذكرنا سابقًا لا يدعم الوسائط المتغيرة. في هذه الحالة ، يتخذ المترجم قرارًا بتجاهل اتفاقية الاتصال المحددة والعودة إلى __cdecl. يلمح هذا السلوك إلى الوصف stdcall, ، المذكور أعلاه. انا اقتبس:

يقوم Callee بتنظيف المكدس ، وبالتالي فإن المترجم فارارج المهام __cdecl.

يمكن ملاحظة ذلك إذا تم تجميع الكود التالي وتفكيك مكالمة إلى الوظيفة.

int __stdcall Bar(int a, int b, ...)
{
  return b * a;
}

سيتم التعامل مع الكود الناتج باسم __cdecl. كما هو ل السبب يتم تعريف هذا بهذه الطريقة ، لا أعرف.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top