为什么在运行时出现CS1666错误?

时间:2018-12-23 12:16:28

标签: c# pointers unsafe

我有以下两个结构:

[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:您不能使用未固定表达式中包含的固定大小的缓冲区。请尝试使用固定语句。”]

这本身对我来说很奇怪,因为这是一个编译器错误,并且没有任何编译问题。没有断点,它将运行,只是没有达到预期。

我自然地尝试修复a)结构和b)缓冲区本身,但均无济于事,说了一些话:“无法通过fixed来获取已经固定的变量的地址

我该如何解决?

1 个答案:

答案 0 :(得分:0)

我在这里没有看到任何问题。尝试以下操作,看看会得到什么:

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

这是给定默认初始化结构的预期输出。