【发布时间】:2017-06-26 11:16:33
【问题描述】:
所以我已经创建了一个结构,我想使用一个简单的 DatagramSocket 发送它。
结构体代码如下:
public struct MsgData
{
private readonly int _value;
private readonly string _descr;
public MsgData(string desc, int value)
{
_descr = desc;
_value = value;
}
public int GetValue()
{
return _value;
}
public string GetDescr()
{
return _descr;
}
}
我继续转换为这样的字节数组:
public static byte[] GetBytes(MsgData message)
{
var size = Marshal.SizeOf(message);
var data = new byte[size];
System.IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(message, ptr, true);
Marshal.Copy(ptr, data, 0, size);
Marshal.FreeHGlobal(ptr);
return data;
}
并将其返回到 MsgData 结构,如下所示:
public static MsgData GetMessage(byte[] bytes)
{
var data = new MsgData();
var size = Marshal.SizeOf(data);
var ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, ptr, size);
data = Marshal.PtrToStructure<MsgData>(ptr);
Marshal.FreeHGlobal(ptr);
return data;
}
但是我得到一个:
System.ArgumentOutOfRangeException: 'Requested range extends past the end of the array.'
尝试在线转换时:
Marshal.Copy(bytes, 0, ptr, size);
我现在要进行简单的序列化,但我想知道为什么这不能按预期工作?
【问题讨论】:
-
发生异常时
bytes.Length是什么? -
您确定
bytes包含足够的字节吗?我会在某处添加if (bytes.Length != size) throw new ArgumentException();。 -
不清楚你打算用这段代码做什么。首先,您没有在结构上指定 StructLayout 属性,在这种情况下未指定打包(您可以根据 x86/x64 检测将使用哪种打包,但代码看起来很脆弱)。此外,您没有在字段上指定“MarshalAs”属性,在这种情况下,您的字符串不会真正被编组。最后,您将“true”传递给 StructureToPtr 的 fDeleteOld 参数,但您分配的内存默认情况下不应包含结构。
-
请解释您想要完成的任务,而不仅仅是“此代码失败,为什么”
-
var size = Marshal.SizeOf(data);
标签: c# exception struct marshalling outofrangeexception