我有以下两个结构:
[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);
第一行按预期方式工作,并通过了断言。 但是,第三行未能通过断言。奇怪的是,当我在第三行上放置断点时,这是我看到的: [描述:VS断点的图片,显示文本“ CS1666:您不能使用未固定表达式中包含的固定大小的缓冲区。请尝试使用固定语句。”]
这本身对我来说很奇怪,因为这是一个编译器错误,并且没有任何编译问题。没有断点,它将运行,只是没有达到预期。
我自然地尝试修复a)结构和b)缓冲区本身,但均无济于事,说了一些话:“无法通过fixed
来获取已经固定的变量的地址
我该如何解决?
答案 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
这是给定默认初始化结构的预期输出。