将内部带有字节数组的结构传递给互操作方法

2024-01-30

我遇到一种情况,必须将结构传递给 C 方法(在我的 C# 文件中声明为 extern)。

然而这个结构相当复杂。我已经成功地使用了 AllocHGlobal 的方法,但我想了解是否可以通过仅传递对结构的引用来使其以这种方式工作。

[StructLayout(LayoutKind.Sequential)]
struct lgLcdBitmapHeader
{
    public Formats Format;
}

[StructLayout(LayoutKind.Explicit)]
struct lgLcdBitmap
{
    [FieldOffset(0)]
    public lgLcdBitmapHeader hdr;
    [FieldOffset(0)]
    public lgLcdBitmap160x43x1 bmp_mono;
    [FieldOffset(0)]
    public lgLcdBitmapQVGAx32 bmp_qvga32;
}

[StructLayout(LayoutKind.Sequential)]
struct lgLcdBitmap160x43x1 : IDisposable
{
    /// <summary>
    /// Format = LGLCD_BMP_FORMAT_160x43x1
    /// </summary>
    public lgLcdBitmapHeader hdr;
    /// <summary>
    /// byte array of size LGLCD_BMP_WIDTH * LGLCD_BMP_HEIGHT, use AllocHGlobal to make code safe
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)BWBitmapSizes.Size)]
    internal byte[] pixels;
}

[StructLayout(LayoutKind.Sequential)]
struct lgLcdBitmapQVGAx32 : IDisposable
{
    /// <summary>
    /// Format = LGLCD_BMP_FORMAT_160x43x1
    /// </summary>
    public lgLcdBitmapHeader hdr;
    /// <summary>
    /// byte array of size LGLCD_QVGA_BMP_WIDTH * LGLCD_QVGA_BMP_HEIGHT * LGLCD_QVGA_BMP_BPP, use AllocHGlobal to make code safe
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)QVGABitmapSizes.Size)]
    internal byte[] pixels;
}

最大的问题是我必须将所有内容包装在一个联合中(lgLcdBitmap 结构)。 实际上,C# 正在抱怨,因为偏移量 0 处有一个对象未​​正确对齐或与另一个对象重叠。

我认为问题与我的字节数组没有实际大小(只有用 SizeConst 声明的大小)这一事实有关。 因为我不想使用固定(它迫使我使用不安全的代码),我想了解如何解决这个问题。

我能想到的唯一想法是声明 Size(在 StructLayout 内)以允许 C# 了解我的结构的大小,但我不确定它是否有效。

我必须调用的方法是这样的:

public extern static uint lgLcdUpdateBitmap([In] int device, [In] ref lgLcdBitmap bitmap, [In] Priorities priority);

关于如何让一切正常运转有什么建议吗?


如果您在托管代码中不需要此类联合,请不要将其设为联合。声明 p/invoke 函数的两个结构体和两个重载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将内部带有字节数组的结构传递给互操作方法 的相关文章

随机推荐