了解 C# P/Invoke 调用约定冲突:Cdecl 与 Stdcall
平台调用 (P/Invoke) 桥接托管 (C#) 和非托管(例如 C)代码。 然而,调用约定的差异可能会导致互操作性问题。
问题的根源
冲突源于 C 和 C# 中默认 P/Invoke 设置之间不同的调用约定处理。
__stdcall
约定。 被调用的函数(callee
)负责堆栈清理。CallingConvention.Winapi
,在 Windows 上相当于 __stdcall
。主要调用约定差异:
核心区别在于:
__stdcall
与 C# 中的 CallingConvention.Winapi
(或 CallingConvention.Stdcall
)。__cdecl
(C 中常用)需要调用函数(caller
)清理堆栈; __stdcall
将其分配给 callee
。不正确的 P/Invoke 声明示例:
当 C 函数使用 CallingConvention.Cdecl
时,不正确的 C# 声明可能会使用 __stdcall
。这会导致堆栈损坏和运行时错误。
正确的 C# 声明:
为了确保兼容性,C# DllImport
属性必须匹配 C 函数的约定:
<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Winapi)] private static extern int InvokedFunction(IntPtr intArg);</code>
防止约定不匹配:
始终确认非托管函数的调用约定并将其精确反映在您的 C# DllImport
声明中。 有关支持的调用约定的详细信息,请参阅 Microsoft 文档。
以上是为什么CDECL和Stdcall在C#p/Invoke中调用惯例不匹配,该如何解决?的详细内容。更多信息请关注PHP中文网其他相关文章!