В чем разница между указателем на функцию и указателем на функцию WINAPI? - PullRequest
3 голосов
/ 19 июня 2010

Я наткнулся на фрагмент кода, который определяет, работает ли приложение в эмулированной среде x32 на ПК x64 здесь

Обычно я понимаю этот код, но есть одна вещь, которую я не понимаю:

1) typedef BOOL (WINAPI * LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

Почему WINAPI должен быть там? Почему так важно знать, что указатель указывает не на мою определенную функцию, а на WINAPI? Будут ли эти 2 указателя отличаться? (по размеру, месту их создания и т. д.)

Спасибо

Кр

Ответы [ 3 ]

4 голосов
/ 19 июня 2010

WINAPI расширяется до __stdcall (в большинстве случаев - вам не следует специально полагаться на это соглашение о вызовах), что является соглашением о вызовах, отличным от принятого по умолчанию, __cdecl. Разница в том, что в __stdcall функция, вызываемая для очистки стека, в то время как в __cdecl вызывающая сторона очищает стек. __stdcall не поддерживает функции varadic (с переменной длиной аргумента), как __cdecl, но __stdcall может быть быстрее и в некоторых случаях уменьшать размер кода.

1 голос
/ 19 июня 2010

WINAPI - это макрос , который обычно содержит подробные сведения о реализации, относящиеся к функциям WinAPI. Как соглашение о вызове. Указанный выше указатель может указывать на любую функцию, если она следует тому же соглашению о вызовах, что и функции WinAPI.

Тот факт, что этот макрос записан как WINAPI, не имеет никакого значения. Это могло быть написано A, HELLO_WORLD или что-то еще. Весь и единственный смысл этого макроса WINAPI состоит в том, чтобы предоставить единственное место, где описаны все эти специфичные для WinAPI соглашения, так что в случае изменения чего-то вам придется изменить его только в одном месте.

Это может быть макрос, который ничего не разрешает.

0 голосов
/ 19 июня 2010

Согласен с предыдущими постами.Кстати, я действительно не понимаю, почему __cdecl по-прежнему считается соглашением о вызовах по умолчанию для C / C ++.

Очевидно, что использование __cdecl приводит к несколько большему коду, чем __stdcall, так как функциязаписывается один раз и обычно вызывается из нескольких частей кода.Да, __cdecl более гибок, поскольку допускает переменную длину аргументов.Но этот shoule будет использоваться IMHO только для соответствующих функций, отмеченных ....

Например, для вызова функций-членов (он же thiscall) Msvc делает именно это: использует __stdcall -подобное соглашение о вызовах, еслиФункция принимает переменные аргументы.(Кроме того, this передается через регистр ECX).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...