OpCodes.Call 字段
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
调用由传递的方法说明符指示的方法。
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) 程序集格式,以及简短的参考摘要:
格式 | 程序集格式 | 说明 |
---|---|---|
28 <T > |
致电 methodDesc |
调用 描述 methodDesc 的方法。 |
堆栈过渡行为(按顺序排列)为:
通过
argN
的方法参数arg1
将推送到堆栈上。通过 的方法参数
arg1
argN
从堆栈中弹出;方法调用使用这些参数执行,并将控件传输到方法描述符引用的方法。 完成后,被调用方方法会生成一个返回值,并将其发送给调用方。返回值将推送到堆栈上。
指令 call
调用随指令一起传递的方法描述符指示的方法。 方法描述符是一个元数据标记,它指示要调用的方法,以及已放置在堆栈上要传递给该方法的参数的数量、类型和顺序,以及要使用的调用约定。 指令 call
前面 tail
可以紧接 (Tailcall) 前缀指令,以指定在转移控制权之前应释放当前方法状态。 如果调用将控制权转移到信任度高于源方法的方法,则不会释放堆栈帧。 相反,执行以静默方式继续, tail
就像没有提供 一样。 元数据令牌携带足够的信息来确定调用是静态方法、实例方法、虚拟方法还是全局函数。 在所有这些情况下,目标地址完全由方法描述符确定, (这与 Callvirt 调用虚拟方法的指令形成对比,其中目标地址还取决于在) 之前推送的实例引用的 Callvirt 运行时类型。
参数按从左到右的顺序放置在堆栈上。 也就是说,计算第一个参数并将其放置在堆栈上,然后第二个参数,然后第三个参数,直到所有必需的参数都按降序排列在堆栈上。 有三个重要的特殊情况:
对实例 (或虚拟) 方法的调用必须将该实例引用推送到任何用户可见参数之前。 实例引用不得为 null 引用。 元数据中携带的签名不包含指针的参数列表中的
this
条目;相反,它使用位来指示方法是否需要传递this
指针。使用
call
(而不是callvirt
) 调用虚拟方法是有效的;这表示将使用方法指定的类(而不是从调用的对象动态指定)解析方法。请注意,可以使用 或
callvirt
指令调用call
委托Invoke
的 方法。
SecurityException 如果系统安全性未授予调用方对调用方法的访问权限,则可能会引发。 当 Microsoft 中间语言 (MSIL) 指令转换为本机代码而不是在运行时时,可能会出现安全检查。
注意
在对值类型调用 System.Object 的方法时,请考虑将 constrained
前缀与 指令一起使用 callvirt
,而不是发出 call
指令。 这样就无需根据值类型是否替代 方法发出不同的 IL,从而避免了潜在的版本控制问题。 在对值类型调用接口方法时,请考虑使用 constrained
前缀,因为可以使用 更改 MethodImpl
实现接口方法的值类型方法。 操作代码中 Constrained 更详细地描述了这些问题。
以下 Emit 方法重载可以使用 call
opcode: