为什么Marshal.WriteInt64方法的代码如此复杂?

ldp*_*ldp 5 c# unsafe marshalling

以下代码反映在.Net Framework中:

[SecurityCritical]
public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val){
    try{
        byte* numPtr = (byte*) (((void*) ptr) + ofs);
        if ((((int) numPtr) & 7) == 0){
            *((long*) numPtr) = val;
        }
        else{
            byte* numPtr2 = (byte*) &val;
            numPtr[0] = numPtr2[0];
            numPtr[1] = numPtr2[1];
            numPtr[2] = numPtr2[2];
            numPtr[3] = numPtr2[3];
            numPtr[4] = numPtr2[4];
            numPtr[6] = numPtr2[6];
            numPtr[7] = numPtr2[7];
        }
    }
    catch (NullReferenceException){
        throw new AccessViolationException();
    }
}
Run Code Online (Sandbox Code Playgroud)

在我看来,*((long*) numPtr) = val足够,而且效率很高.

为什么这么复杂?

zmb*_*mbq 6

虽然经过优化,但看起来相当简单.

注意外部的if - it检查你是否可以在一次操作中编写Int64(如果你传递方法的指针正确对齐,则会发生这种情况 - 指向内存中Int64的开头 - 地址需要是8).

如果你不能在一个操作中写入,代码一次只写一个字节,跳过循环以节省一些时间(这称为'循环展开')