问题描述
|
我有这段代码,它会产生一个错误:
[StructLayout(LayoutKind.Sequential,Pack = 1)]
public struct MyItem
{
[MarshalAs(UnmanagedType.LPWStr)]
public string Name;
public int ID;
public double ID1;
}
private void button1_Click(object sender,RoutedEventArgs e)
{
MyItem[] items = new MyItem[6];
items[0].Name = \"JFK\";
items[0].ID = 35;
items[1].Name = \"LBJ\";
items[1].ID = 36;
items[2].Name = \"Tricky Dicky\";
items[2].ID = 37;
items[3].Name = \"Gerald Ford\";
items[3].ID = 38;
items[4].Name = \"Jimmy Carter\";
items[4].ID = 39;
items[5].Name = \"Ronald Reagan\";
items[5].ID = 40;
IntPtr itemsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MyItem)) *
items.Length);
try
{
IntPtr item = new IntPtr(itemsPtr.ToInt32());
for (int i = 0; i < items.Length; i++)
{
Marshal.StructuretoPtr(items[i],item,true);
item = new IntPtr(item.ToInt32() + Marshal.SizeOf(typeof(MyItem)));
}
}
finally
{
Marshal.FreeHGlobal(itemsPtr);
}
当我运行这段代码时,我得到write protection error in
Marshal.StructuretoPtr(items[i],true);
有什么问题,我该如何解决?
解决方法
您应该将
false
传递给StructureToPtr()
的fDeleteOld
参数。
通过传递true
,您将要求封送员删除item
的内容。由于您是第一次填写,因此会导致内存访问失败,因为内存尚未生效。
该文档指出:
StructureToPtr复制以下内容
到预分配块的结构
ptr参数指向的内存
至。如果fDeleteOld参数为true,
使用以下命令删除预分配的缓冲区
嵌入式指针上适当的删除方法,但缓冲区
必须包含有效数据。
重点是我的。
顺便说一句,我认为循环代码看起来更简洁:
Int32 addr = itemsPtr.ToInt32();
for (int i = 0; i < items.Length; i++)
{
Marshal.StructureToPtr(items[i],new IntPtr(addr),false);
addr += Marshal.SizeOf(typeof(MyItem));
}