如何在IL中表示固定

时间:2017-01-25 14:54:59

标签: c# pinvoke cil

我想知道字段固定是如何用.Net的IL语言表达的, 所以我看了一下示例代码:

struct S
{
    public fixed int buf[8];
}
S s = default(S);
public void MyMethod() {              
    fixed (int* ptr = s.buf){            
        *ptr = 2;        
    }
}

这会生成IL:

.method private hidebysig instance void MyMethod () cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 25 (0x19)
    .maxstack 2
    .locals init (
        [0] int32& pinned
    )

    IL_0000: ldarg.0              // Load argument 0 onto the stack
    IL_0001: ldflda valuetype C/S C::s // Push the address of field of object obj on the stack
    IL_0006: ldflda valuetype C/S/'<buf>e__FixedBuffer' C/S::buf // Push the address of field of object obj on the stack
    IL_000b: ldflda int32 C/S/'<buf>e__FixedBuffer'::FixedElementField // Push the address of field of object obj on the stack
    IL_0010: stloc.0              // Pop a value from stack into local variable 0
    IL_0011: ldloc.0              // Load local variable 0 onto stack
    IL_0012: conv.i               // Convert to native int, pushing native int on stack
    IL_0013: ldc.i4.2             // Push 2 onto the stack as int32
    IL_0014: stind.i4             // Store value of type int32 into memory at address
    IL_0015: ldc.i4.0             // Push 0 onto the stack as int32
    IL_0016: conv.u               // Convert to native unsigned int, pushing native int on stack
    IL_0017: stloc.0              // Pop a value from stack into local variable 0
    IL_0018: ret                  // Return from method, possibly with a value
} // end of method C::MyMethod

我在这里没有看到任何内容,这会明确地告诉GC固定数组,哪条指令实际上负责固定? 还有,还有其他基本操作涉及钉在“引擎盖下”吗?

1 个答案:

答案 0 :(得分:11)

.locals init (
    [0] int32& pinned
)

使用pinned负责固定。本文对此进行了解释:How does the 'fixed' keyword work?文章指出了Standard ECMA-335 Common Language Infrastructure (CLI)的以下摘录:

  

II.7.1.2固定

     

固定的签名编码只能出现在   描述局部变量的签名(§II.15.4.1.3)。一个   固定局部变量的方法正在执行,VES不会   重定位本地引用的对象。也就是说,如果   CLI的实现使用移动对象的垃圾收集器,   收集器不应移动活动引用的对象   固定局部变量。

     

[基本原理:如果使用非托管指针来取消引用托管   物体,这些物体应固定。例如,这种情况发生在   当托管对象传递给设计用于操作的方法时   非托管数据。最终理由]

VES =虚拟执行系统,CLI =公共语言基础设施