繁体   English   中英

使用C#P / Invoke的方法将结构内的数组封送

[英]Marshaling an array inside a Struct with methods using C# P/Invoke

我用C编写了这样的结构

struct IMAGE {
    unsigned int    x, y;
    unsigned char   **data;
};

有人可以告诉我如何编组此结构以在C#中使用吗?

我的解决方案不起作用。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class IMAGE
{
            public UInt32 x;
            public UInt32 y;

            public byte[][] data;
};

托管数组与指针不同。 托管数组需要数组的大小,如果要封送结构,则需要固定大小才能直接封送。

您可以使用MarshalAs属性SizeConst参数设置封送数据时的数据大小。

但是我猜测xy是图像的尺寸, data的大小取决于这些变量。 最好的解决方案是将其IntPtrIntPtr并在需要时访问数据:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class IMAGE
{
    public UInt32 x;
    public UInt32 y;

    private IntPtr data;

    public byte[][] Data
    {
        get
        {
            byte[][] newData = new byte[y][];

            for(int i = 0; i < y; i++)
            {
                newData[i] = new byte[x];
                Marshal.Copy(new IntPtr(data.ToInt64() + (i * x)), newData[i], 0, x);
            }

            return newData;
        }

        set
        {
            for (int i = 0; i < value.Length; i++)
            {
                Marshal.Copy(value[i], 0, new IntPtr(data.ToInt64() + (i * x)), value[i].Length);
            }
        }
    }
}

如果允许使用不安全的代码,则可以将IntPtr更改为byte** ,然后直接使用它。

使用setter,您可能需要在盲目写入非托管内存之前验证值的大小。

我的猜测是:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class IMAGE
{
            public UInt32 x;
            public UInt32 y;

            public ref IntPtr data;
};

p / invoke 备忘单是一个非常方便的参考。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM