№ stdcall Конвенция о созыве призвания очищает стек. Поскольку вызывающая сторона очищает стек, нет возможности узнать во время компиляции, сколько выскочить, поэтому он не может иметь переменные аргументы.
Чтобы иметь переменное количество аргументов функции, вам необходимо использовать cdecl, в котором вызывающий элемент очищает стек. Это весь компилятор, чтобы определить, сколько аргументов передается, и поскольку вызывающий объект очищает стек, он также знает, как много выскочить из стека, когда вызов функции возвращается.
В случае, упомянутом выше, функция объявлена как использующая __stdcall
, которая, как упоминалось ранее, не поддерживает переменные аргументы. В этом случае компилятор принимает решение игнорировать принятое соглашение о вызове и возвращается обратно к __cdecl
. Такое поведение упоминается в описании для stdcall, упомянутом выше. Цитирую:
Вызываемый очищает стек, так что компилятор делает vararg функции __cdecl.
Это можно наблюдать, если скомпилирован следующий код и вызов функции дизассемблирован.
int __stdcall Bar(int a, int b, ...)
{
return b * a;
}
Итоговый код будет рассмотрен как __cdecl
. Что касается причины , то это определено именно так, я не знаю.
http://en.wikipedia.org/wiki/X86_calling_conventions#stdcall – Benjamin
Да, извините. Смутился со старым соглашением о вызове 'pascal'. – linuxuser27
Не быть. Спасибо :) – Benjamin