OpCodes.Call 字段
定义
调用由传递的方法说明符指示的方法。Calls the method indicated by the passed method descriptor.
public: static initonly System::Reflection::Emit::OpCode Call;
public static readonly System.Reflection.Emit.OpCode Call;
staticval mutable Call : System.Reflection.Emit.OpCode
Public Shared ReadOnly Call 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 |
|---|---|---|
28 < T >28 < T > |
致电 methodDesccall methodDesc |
调用所描述的方法 methodDesc 。Call the method described by methodDesc. |
堆栈转换行为顺序如下:The stack transitional behavior, in sequential order, is:
arg1通过将方法参数argN推送到堆栈上。Method argumentsarg1throughargNare pushed onto the stack.arg1通过argN从堆栈中弹出方法自变量; 使用这些参数执行方法调用,并将控件传输到方法说明符所引用的方法。Method argumentsarg1throughargNare popped from the stack; the method call is performed with these arguments and control is transferred to the method referred to by the method descriptor. 完成后,调用方方法将生成一个返回值,并将其发送给调用方。When complete, a return value is generated by the callee method and sent to the caller.将返回值推送到堆栈上。The return value is pushed onto the stack.
call指令调用通过指令传递的方法说明符指示的方法。The call instruction calls the method indicated by the method descriptor passed with the instruction. 方法描述符是一种元数据标记,用于指示要调用的方法,以及要传递到该方法的堆栈上的参数的数量、类型和顺序,以及要使用的调用约定。The method descriptor is a metadata token that indicates the method to call and the number, type, and order of the arguments that have been placed on the stack to be passed to that method as well as the calling convention to be used. call指令前面可以跟一个 tail (Tailcall) 前缀指令,以指定在传输控件之前应释放当前方法状态。The call instruction can be immediately preceded by a tail (Tailcall) prefix instruction to specify that the current method state should be released before transferring control. 如果调用将控制转移到比源方法更高的信任方法,则不会释放堆栈帧。If the call transfers control to a method of higher trust than the origin method, the stack frame is not released. 相反,执行将以无提示方式继续,就好像 tail 尚未提供。Instead, the execution continues silently as if the tail had not been supplied. 元数据标记携带足够的信息来确定调用是静态方法、实例方法、虚方法还是全局函数。The metadata token carries sufficient information to determine whether the call is to a static method, an instance method, a virtual method, or a global function. 在所有这些情况下,都完全从方法说明符确定了目标地址 (将此与 Callvirt 调用虚拟方法的指令对比,其中目标地址也依赖于) 之前推送的实例引用的运行时类型 Callvirt 。In all of these cases the destination address is determined entirely from the method descriptor (contrast this with the Callvirt instruction for calling virtual methods, where the destination address also depends upon the runtime type of the instance reference pushed before the Callvirt).
自变量以从左到右的顺序放置在堆栈上。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. 有三个重要的特殊情况:There are three important special cases:
对实例 (或虚) 方法的调用必须将该实例引用推送到任何用户可见参数之前。Calls to an instance (or virtual) method must push that instance reference before any of the user-visible arguments. 实例引用不得为空引用。The instance reference must not be a null reference. 在元数据中携带的签名不包含用于指针的参数列表中的条目
this; 相反,它使用位来指示该方法是否要求传递this指针。The signature carried in the metadata does not contain an entry in the parameter list for thethispointer; instead, it uses a bit to indicate whether the method requires passing thethispointer.使用
call(而不是) 调用虚拟方法是有效的callvirt; 这表示使用方法指定的类(而不是从所调用的对象动态指定)解析方法。It is valid to call a virtual method usingcall(rather thancallvirt); this indicates that the method is to be resolved using the class specified by method rather than as specified dynamically from the object being invoked.请注意,
Invoke可以使用或指令调用委托的方法callcallvirt。Note that a delegate'sInvokemethod can be called with either thecallorcallvirtinstruction.
SecurityException 如果系统安全不允许调用方访问调用的方法,则可能会引发。SecurityException may be thrown if system security does not grant the caller access to the called method. 当 Microsoft 中间语言 (MSIL) 指令转换为本机代码而不是运行时,可能会发生安全检查。The security check may occur when the Microsoft Intermediate Language (MSIL) instructions are converted to native code rather than at run time.
备注
当在值类型上调用 System.object 的方法时,请考虑将 constrained 前缀与指令一起使用, callvirt 而不是发出 call 指令。When calling methods of System.Object on value types, consider using the constrained prefix with the callvirt instruction instead of emitting a call instruction. 这就不必发出不同的 IL,具体取决于值类型是否重写方法,避免出现潜在的版本控制问题。This removes the need to emit different IL depending on whether or not the value type overrides the method, avoiding a potential versioning problem. constrained对值类型调用接口方法时,请考虑使用前缀,因为实现接口方法的值类型方法可使用进行更改 MethodImpl 。Consider using the constrained prefix when invoking interface methods on value types, since the value type method implementing the interface method can be changed using a MethodImpl. 操作码中更详细地介绍了这些问题 Constrained 。These issues are described in more detail in the Constrained opcode.
以下 Emit 方法重载可以使用 call 操作码:The following Emit method overloads can use the call opcode:
备注
为 EmitCall 调用提供了方法 varargs 。The EmitCall method is provided for varargs calls. 使用 Emit 方法进行正常调用。Use the Emit method for normal calls.