【发布时间】:2016-07-20 23:25:53
【问题描述】:
我正在尝试使用 byte[] 字段创建类似联合的结构。所以下一个类型声明会导致运行时出错:
[StructLayout(LayoutKind.Explicit)]
public struct Int64ByteArr
{
[FieldOffset(0)]
public UInt64 u64;
[FieldOffset(0)]
public Int64 s64;
[FieldOffset(0), MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] bytes;
}
当调用使用该类型变量的函数时,程序会导致具有该描述的异常:
Необработанное исключение типа "System.TypeLoadException" в System.Windows.Forms.dll Дополнительные сведения: Не удалось загрузить тип "Int64ByteArr" из сборки "ChalengeCalc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", так как он содержит поле объекта со смещением 0, которое неверно выровнено или перекрыто полем, не представляющим объект .
翻译成英文:System.Windows.Forms.dll 中“System.TypeLoadException”类型的未处理异常) 附加信息:无法从“ChalengeCalc,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”程序集加载类型“Int64ByteArr”,因为它包含 oaffset 0 的对象字段,该字段与未显示的溢出字段错误对齐一个对象
我也试试这个变种:
[StructLayout(LayoutKind.Sequential)]
public struct ByteArr8
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] bytes;
public Byte this[int idx]
{
get
{
if (idx < 0 || idx > 7) return 0;
return bytes[idx];
}
set
{
if (idx < 0 || idx > 7) return;
bytes[idx] = value;
}
}
}
[StructLayout(LayoutKind.Explicit)]
public struct Int64ByteArr
{
[FieldOffset(0)]
public UInt64 u64;
[FieldOffset(0)]
public Int64 s64;
[FieldOffset(0)]
public ByteArr8 bytes;
}
它挂起并出现相同的异常。所以有一个问题:“怎么做?”
【问题讨论】:
-
您不能将对像 byte[] 这样的引用类型的引用与值类型值重叠。这搞砸了垃圾收集器。您必须改用固定大小的缓冲区。由于数组与 Int64 大小相同,另一个非常简单的解决方法是使用 BitConverter.GetBytes() 读取字节值。
标签: c# marshalling unions