CallingConvention 枚举
指定调用在非托管代码中实现的方法所需的调用约定。
[C#]
[Serializable]
public enum CallingConvention
请始终使用 CallingConvention 枚举,而不是 CALLCONV 枚举在托管代码中指定一个调用约定。后者仅作 COM 定义之用。DllImportAttribute 和 System.Reflection.Emit 中的若干类使用 CallingConvention 枚举,以动态发出平台调用签名。
成员
成员名称说明
Cdecl调用方清理堆栈。这使您能够调用具有 varargs 的函数(如 Printf),使之可用于接受可变数目的参数的方法。
FastCall不支持此调用约定。
StdCall被调用方清理堆栈。这是使用平台 invoke 调用非托管函数的默认约定。
ThisCall第一个参数是 this 指针,它存储在寄存器 ECX 中。其他参数被推送到堆栈上。此调用约定用于对从非托管 DLL 导出的类调用方法。
Winapi
受 .NET Framework 精简版的支持。此成员实际上不是调用约定,而是使用了默认平台调用约定。例如,在 Windows 上默认为 StdCall,在 Windows CE .NET 上默认为 Cdecl。
示例
[Visual Basic, C#, C++] 下面的示例演示了如何应用 Cdecl 调用约定,因为由调用方负责清理堆栈,所以必须使用此调用约定。
[C#]
using System;
using System.Runtime.InteropServices;
public class LibWrap
{
// C# doesn't support varargs so all arguments must be explicitly defined.
// CallingConvention.Cdecl must be used since the stack is
// cleaned up by the caller.
// int printf( const char *format [, argument]... )
[DllImport("msvcrt.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
public static extern int printf(String format, int i, double d);
[DllImport("msvcrt.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
public static extern int printf(String format, int i, String s);
}
public class App
{
public static void Main()
{
LibWrap.printf("\nPrint params: %i %f", 99, 99.99);
LibWrap.printf("\nPrint params: %i %s", 99, "abcd");
}
}