Marshal.StructureToPtr失败了bool和固定大小的数组?

时间:2012-02-05 19:09:10

标签: c# marshalling

如果我使用StructureToPtr封送此结构,然后使用PtrToStructure再次解组,我的第一个节点的y = {1,2},而我的第二个节点的y = {1,0}。

我不知道为什么,也许我的结构在某种程度上是坏的?从结构中删除bool使其有效。

using System;
using System.Runtime.InteropServices;

namespace csharp_test
{
    unsafe class Program
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct Node
        {
            public bool boolVar;
            public fixed int y[2];
        }

        unsafe static void Main(string[] args)
        {
            Node node = new Node();

            node.y[0] = 1;
            node.y[1] = 2;
            node.boolVar = true;

            int size = sizeof(Node);
            IntPtr ptr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(node, ptr, false);
            Node node2 = (Node)Marshal.PtrToStructure(ptr, typeof(Node));
            Marshal.FreeHGlobal(ptr);
        }
    }
}

2 个答案:

答案 0 :(得分:9)

这确实是错的。它是StructureToPtr()调用,无法复制足够的字节。你可以通过使用Debug + Windows + Memory + Memory1并在地址栏中输入“ptr”来看到这一点。使用sizeof运算符isn't correct但实际上不是问题的根源。无论数组长度如何,仅复制数组的第一个元素。不确定导致此问题的原因,我从不在pinvoke中使用 fixed 。我只能推荐传统的pinvoke方式,它的工作正常:

unsafe class Program {
    [StructLayout(LayoutKind.Sequential)]
    public struct Node {
        public bool boolVar;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public int[] y;
    }

    unsafe static void Main(string[] args) {
        Node node = new Node();
        node.y = new int[2];

        node.y[0] = 1;
        node.y[1] = 2;
        node.boolVar = true;

        int size = Marshal.SizeOf(node);
        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(node, ptr, false);
        Node node2 = (Node)Marshal.PtrToStructure(ptr, typeof(Node));
        Marshal.FreeHGlobal(ptr);
    }

如果您想将其提交给CLR互操作大师,请发布到connect.microsoft.com。

答案 1 :(得分:0)

您还应该在使用之前打包结构或类。这对我有用,几乎和memcpy一样好

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class SomeClass
{
}