C#中的编组结构

时间:2011-05-27 21:22:06

标签: c# marshalling

我有这段代码,它会产生错误:

    [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], item, true);

问题是什么?如何解决?

1 个答案:

答案 0 :(得分:4)

您应该将false传递给fDeleteOld的{​​{1}}参数。

通过传递StructureToPtr(),您要求编组人员删除true的内容。由于您是第一次填写此内容,因此内存访问失败,因为内存尚未生效。

文档说明:

  

StructureToPtr复制内容   结构到预先分配的块   ptr参数指向的内存   至。如果fDeleteOld参数为true,   删除预分配的缓冲区   嵌入式指针上的相应删除方法,但缓冲区   必须包含有效数据

重点是我的。

顺便说一句,我认为循环代码看起来像这样:

item