При использовании 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) не заботится о соглашениях о вызовах, но надеюсь, что вышесказанное устранит некоторую путаницу.

Другие вопросы по тегам