C#结构包括字节数组和长值
本文关键字:数组 字节数 结构 包括 字节 | 更新日期: 2023-09-27 18:25:09
这是我的代码,用户可以使用一个带有字节的长变量,但当程序运行时,会发生异常并显示以下内容:
Test.exe 中发生类型为"System.TypeLoadException"的未处理异常
其他信息:无法从程序集"Test,"加载类型"Test.MyU32",Version=1.0.0.0,Culture=neutral,PublicKeyToken=null',因为它包含偏移量为0的对象字段被非对象错误对齐或重叠领域
[StructLayout(LayoutKind.Explicit)]
public struct MyU32
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] Bytes;
[FieldOffset(0)]
public long Value;
}
请帮我怎么处理!
您的代码用例不起作用,因为您重叠了引用和值类型(64位int)。可以重叠不同的值类型和不同的引用,但不能混合使用。
但即使它们有效,在C#中,这种低级别的黑客通常也是个坏主意。我建议使用进行转换的属性,而不是低级别的并集。
也许你真正想要的是:
internal static class ByteIntegerConverter
{
public static UInt32 LoadLittleEndian32(byte[] buf, int offset)
{
return
(UInt32)(buf[offset + 0])
| (((UInt32)(buf[offset + 1])) << 8)
| (((UInt32)(buf[offset + 2])) << 16)
| (((UInt32)(buf[offset + 3])) << 24);
}
public static void StoreLittleEndian32(byte[] buf, int offset, UInt32 value)
{
buf[offset + 0] = (byte)value;
buf[offset + 1] = (byte)(value >> 8);
buf[offset + 2] = (byte)(value >> 16);
buf[offset + 3] = (byte)(value >> 24);
}
}
UInt32 value = ByteIntegerConverter.LoadLittleEndian32(buf, offset);
// do something with `value`
ByteIntegerConverter.StoreLittleEndian32(buf, offset, value);
不管计算机的本机端序如何,它总是使用小端序。如果您想要本机端序,可以使用BitConverter.IsLittleEndian
进行检查,如果它是大端序,则可以使用不同的移位常量。
我不能完全确定,但我认为问题是由值类型和引用类型之间的重叠引起的。应该可以只重叠值类型。因为如果可以重叠值类型&引用类型,您可以直接更改引用。出于明显的安全原因,这是不可能的。
由于byte[]
是引用类型(与.NET中的所有数组一样)。Value
不能与Bytes
重叠。
如果你习惯了C,你的结构(没有明确的布局)将"类似"于:
struct MyU32
{
byte* Bytes;
long Value;
}
但它与不同
struct MyU32
{
byte Bytes[4];
long Value;
}
我解决了我的问题
Tanx给所有花时间的人。
public struct MyU32
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] Bytes;
public uint Value
{
get { return ((uint)Bytes[0] + Bytes[1] << 8 + Bytes[2] << 16 + Bytes[3] << 24); }
set
{
Bytes[0] = (byte)(value & 0xFF);
Bytes[1] = (byte)(value>>8 & 0xFF);
Bytes[2] = (byte)(value>>16 & 0xFF);
Bytes[3] = (byte)(value>>24 & 0xFF);
}
}
}