Marshal.StructureToPtr因布尔和固定大小数组而失败

本文关键字:小数 数组 失败 StructureToPtr 布尔 Marshal | 更新日期: 2023-09-27 18:22:28

如果我用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);
        }
    }
}

Marshal.StructureToPtr因布尔和固定大小数组而失败

这确实出了问题。是StructureToPtr()调用未能复制足够的字节。您可以使用Debug+Windows+Memory+Memory1并将"ptr"放在地址框中来看到这一点。使用sizeof运算符是不正确的,但实际上并不是问题的根源。无论数组长度如何,都只复制数组的第一个元素。不确定是什么原因导致了这个问题,我从未在pinvoke中使用修复。我只能推荐传统的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。

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

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