在 64 位 .NET 应用程序中是否忽略调用约定

本文关键字:调用 约定 是否 NET 应用程序 | 更新日期: 2023-09-27 18:30:43

通过 P/Invoke 通过显式 64 位 .NET 应用程序与 64 位本机库交互时,是否有效地忽略了 DllImport 属性中的 CallingConvention 属性?

我问这个是因为在"传统"x86 上,您必须指定调用方或被调用方清理堆栈变量的方式(以及函数本身如何使用某些 CPU 寄存器等);但据我了解,x64 只有一个约定,__fastcall(尽管最近添加了__vectorcall)。

那么,无论您为 CallingConvention 属性设置了什么,CLR 是否只是继续使用 __fastcall x64 约定封送函数调用?

在 64 位 .NET 应用程序中是否忽略调用约定

是的,完全忽略了。 64 位 pinvoke 编组器仅支持 x64 ABI,松散地基于 __fastcall。 非常松散。 如果您指定 CallingConvention,则不会收到异常,它只是耸耸肩。

请注意,__vectorcall并非特定于 x64,还有一个 x86 变体。 pinvoke 封送器都不支持这两种方法,您必须编写一个 C++/CLI 包装器。 支持它几乎没有意义,.NET 抖动仍然具有非常弱的 SSE2/AVX 支持。 System.Numerics.Vector中的一点带有RyuJIT抖动,VS2015附带的新x64抖动,但还不能将参数传递给方法。 苛刻的对齐要求将需要非常激烈的CLR重写,远距离的未来音乐。