OpCodes.Calli 字段


通过调用约定描述的参数调用在计算堆栈上指示的方法(作为指向入口点的指针)。Calls the method indicated on the evaluation stack (as a pointer to an entry point) with arguments described by a calling convention.

public: static initonly System::Reflection::Emit::OpCode Calli;
public static readonly System.Reflection.Emit.OpCode Calli;
 staticval mutable Calli : System.Reflection.Emit.OpCode
Public Shared ReadOnly Calli As OpCode 



下表列出了指令的十六进制和 Microsoft 中间语言(MSIL)程序集格式以及简短的参考摘要:The following table lists the instruction's hexadecimal and Microsoft Intermediate Language (MSIL) assembly format, along with a brief reference summary:

格式Format 程序集格式Assembly Format 说明Description
29 < T >29 < T > calli callSiteDescrcalli callSiteDescr 使用调用约定描述的参数调用指向的方法。Calls the method pointed to with arguments described by the calling convention.

堆栈转换行为顺序如下:The stack transitional behavior, in sequential order, is:

  1. 方法参数 arg1argN 将被推送到堆栈上。Method arguments arg1 through argN are pushed onto the stack.

  2. 方法输入指针被推送到堆栈上。The method entry pointer is pushed onto the stack.

  3. 方法参数 arg1argN,并从堆栈中弹出方法输入指针;执行对方法的调用。Method arguments arg1 through argN and the method entry pointer are popped from the stack; the call to the method is performed. 完成后,调用方方法将生成一个返回值,并将其发送给调用方。When complete, a return value is generated by the callee method and sent to the caller.

  4. 将返回值推送到堆栈上。The return value is pushed onto the stack.

@No__t-0 指令使用参数 arg1argN 调用方法输入指针。The calli instruction calls the method entry pointer with the arguments arg1 through argN. 这些参数的类型由特定的调用约定(callSiteDesc)描述。The types of these arguments are described by the specific calling convention (callSiteDesc). @No__t-0 指令前面可以跟 tail 前缀(Tailcall),以指定在传输控制之前应释放当前方法状态。The calli instruction may be immediately preceded by a tail prefix (Tailcall) to specify that the current method state should be released before transferring control. 如果调用会将控制传输到比源方法更高的信任方法,则不会释放堆栈帧;相反,执行将会以静默方式继续,就好像尚未提供 tailIf the call would transfer control to a method of higher trust than the origin method the stack frame will not be released; instead, the execution will continue silently as if the tail had not been supplied.

假定方法输入指针是指向本机代码(目标计算机)的特定指针,该指针可以使用调用约定描述的参数(独立签名的元数据标记)合法调用。The method entry pointer is assumed to be a specific pointer to native code (of the target machine) that can be legitimately called with the arguments described by the calling convention (a metadata token for a stand-alone signature). 此类指针可使用 @no__t 0 或 @no__t 指令创建,或从本机代码传入。Such a pointer can be created using the Ldftn or Ldvirtftn instructions, or passed in from native code.

不动态检查调用约定,因此,如果目标不实际使用指定的调用约定,则使用 calli 指令的代码将无法正常运行。The calling convention is not checked dynamically, so code that uses a calli instruction does not work correctly if the destination does not actually use the specified calling convention.

自变量以从左到右的顺序放置在堆栈上。The arguments are placed on the stack in left-to-right order. 也就是说,第一个参数是计算并放置在堆栈上,然后是第三个参数,然后是第三个参数,直到所有必需的参数按降序排列。That is, the first argument is computed and placed on the stack, then the second argument, then the third, until all necessary arguments are atop the stack in descending order. 实例或虚方法的参数生成代码序列必须在任何用户可见参数之前推送该实例引用(不得为空引用)。The argument-building code sequence for an instance or virtual method must push that instance reference (which must not be a null reference) before any of the user-visible arguments.

如果系统安全不允许调用方访问调用的方法,则可能引发 SecurityExceptionSecurityException may be thrown if the system security does not grant the caller access to the called method. 当 Microsoft 中间语言(MSIL)指令转换为本机代码而不是运行时时,可能会进行安全检查。The security check can occur when the Microsoft Intermediate Language (MSIL) instructions are converted to native code rather than at runtime.

以下 EmitCalli 方法可用于在堆栈上执行 @no__t 的指令。The following EmitCalli methods can be used to perform a calli instruction on the stack. 请注意,应通过以下方法调用 calli,而不是使用 @no__t 类将指令直接置于堆栈上。Note that calli should be called through the below methods rather than using the Emit class to place the instruction directly on the stack.

  • 对于使用托管调用约定的调用,EmitCalli (操作码、CallingConventions、Type、type []、Type [])。ILGenerator.EmitCalli(Opcode, CallingConventions, Type, Type[], Type[]) for calls using a managed calling convention.

  • ILGenerator 使用非托管调用约定调用 EmitCalli (Opcode,CallingConvention,Type,Type [])。ILGenerator.EmitCalli(Opcode, CallingConvention, Type, Type[]) for calls using an unmanaged calling convention.