При использовании PInvoke зачем использовать __stdcall?

Я использовал PInvoke, чтобы мое приложение C # вызывало функции C ++, которые я написал.

Теперь я постоянно и везде слышу, что мне нужно определить эти внешне доступные функции с помощью __stdcall условность. Мой вопрос: почему?

До сих пор я случайно проигнорировал этот совет, и все работает как шарм. Когда я добавлю __stdcall к моим функциям все продолжает работать одинаково (или, по крайней мере, так кажется).

Эта статья Говорит, что __stdcall используется для битовых функций Win32, но я собираюсь на платформе x64. Означает ли это, что я не должен использовать __stdcall в конце концов или это означает, что я упускаю что-то еще?

И, пожалуйста, используйте простой английский при ответе. 😉 Строки как это (цитируется из статьи, которую я связал):

Вызываемый объект очищает стек, поэтому компилятор выполняет функции vararg __cdecl.

заставь мой мозг почувствовать, как сквозь него дует рукавица.

3

Решение

Существует только одно соглашение о вызовах в x64, и поэтому не имеет значения, какое соглашение о вызовах вы указываете. Это всегда игнорируется на x64.

На x86 важно убедиться, что соглашения о вызовах совпадают на обеих сторонах интерфейса. Так что, если вы когда-нибудь ожидаете запустить свой код на x86, было бы разумно получить это прямо сейчас.

4

Другие решения

Соглашения о вызовах являются исторической случайностью в 32-битном коде. В 64-битном коде есть только одно соглашение, поэтому все, что вы объявляете, не имеет значения.

Если вы создаете неуправляемую 32-разрядную библиотеку DLL, которая может использоваться кодом, который не был написан на C или C ++, тогда объявление вашей экспортированной функции с помощью __stdcall поможет уменьшить количество аварий. Большинство языковых сред поддержки поддерживают взаимодействие, чтобы разрешить вызовы ОС, поэтому они делают __stdcall значением по умолчанию.

Более подробную информацию о соглашениях о вызовах и оформлении имен вы найдете в этот ответ

2

Вам не хватает того факта, что x64 и Win32 — это совершенно разные вещи. Win32 — это C API для взаимодействия с Windows, и его соглашение о вызовах является __stdcallтогда как x64 или x86-64 — это размер ваших регистров процессора. (т. е. шириной 64 бита).

В статье в Википедии под соглашением о вызовах x86-64:

При компиляции для архитектуры x64 в контексте Windows (с использованием инструментов Microsoft или сторонних разработчиков) существует только одно соглашение о вызовах — описанное здесь, так что теперь все stdcall, thiscall, cdecl, fastcall и т. Д. Едины. и то же самое.

Очевидно, x64 (AMD) не заботится о соглашениях о вызовах, но надеюсь, что вышесказанное устранит некоторую путаницу.

2