代码之家  ›  专栏  ›  技术社区  ›  John

为什么我会得到一个CS1666错误,显然是在运行时?

  •  2
  • John  · 技术社区  · 6 年前

    我有两个结构:

    [StructLayout(LayoutKind.Sequential)]
    unsafe struct ReinterpretableStruct
    {
        public int a; // 0 - 1 - 2 - 3
        public fixed byte buffer[4]; // 4 - 5 - 6 - 7
        public double x; // 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15
    }
    
    [StructLayout(LayoutKind.Sequential)]
    unsafe struct OtherReinterpretableStruct
    {
        public ushort a; // 0 - 1
        public fixed byte buffer[2]; // 2 - 3
        public float y; // 4 - 5 - 6 - 7
        public long w; // 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15
    }
    

    它们都是16字节,没有填充,如注释所示。 我一直在处理固定缓冲区和指针转换,并有一个奇怪的问题。

    Assert.True(b.a == *(ushort*)&a.a);
    string bufferAsUnsignedShort = (*(ushort*) b.buffer).ToString();
    Assert.True(*(ushort*)b.buffer == *((ushort*)&a) + 1);
    Assert.True(b.y == *(float*)a.buffer);
    Assert.True(b.w == *(long*)&a.x);
    

    第一行按预期工作,传递断言。 然而,第三行的断言失败了。奇怪的是,当我在第三行放置断点时,我看到的是: A picture of a VS breakpoint showing the text "CS1666: You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement." [说明:VS断点的图片,显示文本“CS1666:不能使用非固定表达式中包含的固定大小缓冲区。尝试使用固定语句。“]

    这本身对我来说很奇怪,因为那是一个编译器错误,没有编译问题。如果没有断点,它将运行,正如预期的那样。

    fixed

    我该如何解决?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Matthew Watson    6 年前

    我看这里没有什么问题。试试下面的方法,看看你得到了什么:

    using System;
    using System.Runtime.InteropServices;
    
    namespace Demo
    {
        [StructLayout(LayoutKind.Sequential)]
        unsafe struct ReinterpretableStruct
        {
            public       int    a;         // 0 - 1 - 2 - 3
            public fixed byte   buffer[4]; // 4 - 5 - 6 - 7
            public       double x;         // 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15
        }
    
        [StructLayout(LayoutKind.Sequential)]
        unsafe struct OtherReinterpretableStruct
        {
            public       ushort a;         // 0 - 1
            public fixed byte   buffer[2]; // 2 - 3
            public       float  y;         // 4 - 5 - 6 - 7
            public       long   w;         // 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15
        }
    
        class Program
        {
            public static void Main()
            {
                unsafe
                {
                    var a = new ReinterpretableStruct();
                    var b = new OtherReinterpretableStruct();
    
                    int size1 = *(ushort*) b.buffer;
                    int size2 = *((ushort*) &a) + 1;
    
                    Console.WriteLine(size1);
                    Console.WriteLine(size2);
                }
            }
        }
    }
    

    当我运行它时,我看到以下输出:

    0
    1