При использовании PInvoke зачем использовать __stdcall?
Я использовал PInvoke, чтобы мое приложение C# вызывало функции C++, которые я написал.
Теперь я постоянно и везде слышу, что мне нужно определить эти внешне доступные функции с помощью __stdcall
условность. Мой вопрос: почему?
До сих пор я случайно проигнорировал этот совет, и все работает как шарм. Когда я добавлю __stdcall
к моим функциям все продолжает работать одинаково (или, по крайней мере, так кажется).
В этой статье говорится, что __stdcall
используется для битовых функций Win32, но я собираюсь на платформе x64. Означает ли это, что я не должен использовать __stdcall
в конце концов или это означает, что я упускаю что-то еще?
И, пожалуйста, используйте простой английский при ответе.;-) Строки как это (цитируется из статьи, которую я связал):
Вызываемый объект очищает стек, поэтому компилятор выполняет функции vararg __cdecl.
заставь мой мозг почувствовать, как сквозь него дует рукавица.
3 ответа
Существует только одно соглашение о вызовах в x64, и поэтому не имеет значения, какое соглашение о вызовах вы указываете Это всегда игнорируется на x64.
На x86 важно убедиться, что соглашения о вызовах совпадают на обеих сторонах интерфейса. Так что, если вы когда-нибудь ожидаете запустить свой код на x86, было бы разумно получить это прямо сейчас.
Соглашения о вызовах являются исторической случайностью в 32-битном коде. В 64-битном коде есть только одно соглашение, поэтому все, что вы объявляете, не имеет значения.
Если вы создаете неуправляемую 32-разрядную библиотеку DLL, которая может использоваться кодом, который не был написан на C или C++, тогда объявление вашей экспортированной функции с помощью __stdcall поможет уменьшить количество аварий. Большинство языковых сред поддержки поддерживают взаимодействие, чтобы разрешить вызовы ОС, поэтому они делают __stdcall по умолчанию.
В этом ответе вы найдете более подробную информацию о соглашениях о вызовах и оформлении имен.
Вам не хватает того факта, что x64 и Win32 - это совершенно разные вещи. Win32 - это C API для взаимодействия с Windows, и его соглашение о вызовах __stdcall
тогда как x64 или x86-64 - это размер регистров вашего процессора. (т. е. шириной 64 бита).
В статье в Википедии под соглашением о вызовах x86-64:
При компиляции для архитектуры x64 в контексте Windows (с использованием инструментов Microsoft или сторонних разработчиков) существует только одно соглашение о вызовах - описанное здесь, так что теперь все stdcall, thiscall, cdecl, fastcall и т. Д. и то же самое.
Очевидно, x64 (AMD) не заботится о соглашениях о вызовах, но надеюсь, что вышесказанное устранит некоторую путаницу.