我已经看到了一些将byte []复制到struct的方法,反之亦然。但是,我想知道是否可以将byte []指针强制转换为结构(就像你在C中那样)。
我希望能够将一个byte []转换为结构,对结构进行更改,并使更改自动出现在byte []中。
谢谢, 礼
答案 0 :(得分:1)
你只是施放指针(有时你需要通过中间的void*
):
struct Foo
{
public int Bar;
}
static unsafe void Main()
{
byte[] buffer = new byte[10];
fixed (byte* untyped = buffer)
{
var typed = (Foo*)untyped;
typed[0].Bar = 123;
}
// buffer has the changes
}
如果需要偏移到缓冲区,请使用byte* untyped = &buffer[offset]
。
如果你想要一个原始结构指针,那么:
fixed (byte* ptr = buffer)
{
var typed = (Foo*)ptr;
Foo* foo = &typed[0];
foo->Bar = 123;
}
但请注意,您无法将Foo*
传递给期望Foo
或ref Foo
的方法。
答案 1 :(得分:0)
我发现这种方法是最简单的实现我想要的..如果你定义结构使得byte []与元素重叠,那么副本在struct和byte []之间是有效透明的(假设是endian-ness是你所期望的;就我而言,它是)。
[StructLayout(LayoutKind.Explicit)]
public unsafe struct ListEntry {
[System.Runtime.InteropServices.FieldOffset(0)] public fixed byte raw[512];
[System.Runtime.InteropServices.FieldOffset(0)] public byte version;
[System.Runtime.InteropServices.FieldOffset(1)] public UInt16 magic;
[System.Runtime.InteropServices.FieldOffset(3)] public UInt32 start_time;
[System.Runtime.InteropServices.FieldOffset(7)] public UInt16 run_id;
[System.Runtime.InteropServices.FieldOffset(9)] public UInt16 channels;
[System.Runtime.InteropServices.FieldOffset(11)] public UInt16 sampling_rate;
[System.Runtime.InteropServices.FieldOffset(13)] public UInt32 start_sector;
[System.Runtime.InteropServices.FieldOffset(510)] public UInt16 checksum;
}
答案 2 :(得分:0)
我建议你最好的选择,如果速度不是很关键,可能是将数据存储在byte[]
中,并且有一个类,其中包含对byte[]
的不可变引用并具有get / set方法访问数组的属性。属性获取/集合将始终反映并反映在数组的状态中,因为数组本身将保持对象的状态。不需要“不安全”的代码。
方法可能类似于:
public static class IntPack
{ // All methods ssume unchecked arithmetic
public static Int16 FetchI16LE(this byte[] dat, int offset)
{
return (Int16)(dat[offset] + (dat[offset + 1] << 8));
}
public static Int32 FetchI32LE(this byte[] dat, int offset)
{
return dat[offset] + (dat[offset + 1] << 8) +
(dat[offset + 2] << 16) + (dat[offset + 3] << 24);
}
public static void StuffI16LE(this byte[] dat, int offset, int value)
{
dat[offset] = (byte)(value);
dat[offset+1] = (byte)(value >> 8);
}
public static void StuffI32LE(this byte[] dat, int offset, int value)
{
dat[offset] = (byte)(value);
dat[offset + 1] = (byte)(value >> 8);
dat[offset + 2] = (byte)(value >> 16);
dat[offset + 3] = (byte)(value >> 24);
}
}
指示的方法假设小端排序。人们可以轻松地为big-endian编写相应的__BE方法。