指向C结构体第一个元素的指针与指向该结构体的指针相同.但不是c#:互操作问题

本文关键字:指针 结构体 问题 互操作 元素 第一个 指向 | 更新日期: 2023-09-27 18:09:40

抱歉的标题,我有一个互操作问题。我正在使用的C dll请求,在一个函数中,指向结构体的第一个元素的指针,但是这在C中可以转换为指向该结构体的指针,而这在c#中是不一样的。我如何"模拟"这种行为(我需要在c#中使用该函数)。

我将在这里发布一个代码片段:

[StructLayout(LayoutKind.Sequential)]
struct lgLcdBitmapHeader
{
    public Formats Format;
}
[StructLayout(LayoutKind.Explicit)]
struct lgLcdBitmap
{
    [FieldOffset(0)]
    lgLcdBitmapHeader hdr;
    [FieldOffset(0)]
    lgLcdBitmap160x43x1 bmp_mono;
    [FieldOffset(0)]
    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>
    public IntPtr pixels;
    public void SetPixels(byte[] value)
    {
        if (value.Length < (int)BitmapSizes.Size)
            throw new InvalidOperationException(string.Format("Byte array must be at least of size {0}", (int)BitmapSizes.Size));
        if (pixels == IntPtr.Zero)
            pixels = Marshal.AllocHGlobal((int)BitmapSizes.Size);
        Marshal.Copy(value, 0, pixels, (int)BitmapSizes.Size);
    }
    public void GetPixels(byte[] arrayToBeFilled)
    {
        if (arrayToBeFilled.Length < (int)BitmapSizes.Size)
            throw new InvalidOperationException(string.Format("Byte array must be at least of size {0}", (int)BitmapSizes.Size));
        Marshal.Copy(pixels, arrayToBeFilled, 0, (int)BitmapSizes.Size);
    }
    public void Dispose()
    {
        if (pixels != IntPtr.Zero)
            Marshal.FreeHGlobal(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>
    public IntPtr pixels;

    public void SetPixels(byte[] value)
    {
        if (value.Length < (int)QVGABitmapSizes.Size)
            throw new InvalidOperationException(string.Format("Byte array must be at least of size {0}", (int)QVGABitmapSizes.Size));
        if (pixels == IntPtr.Zero)
            pixels = Marshal.AllocHGlobal((int)QVGABitmapSizes.Size);
        Marshal.Copy(value, 0, pixels, (int)QVGABitmapSizes.Size);
    }
    public void GetPixels(byte[] arrayToBeFilled)
    {
        if (arrayToBeFilled.Length < (int)QVGABitmapSizes.Size)
            throw new InvalidOperationException(string.Format("Byte array must be at least of size {0}", (int)QVGABitmapSizes.Size));
        Marshal.Copy(pixels, arrayToBeFilled, 0, (int)QVGABitmapSizes.Size);
    }
    public void Dispose()
    {
        if (pixels != IntPtr.Zero)
            Marshal.FreeHGlobal(pixels);
    }
}

问题是函数要求lgLcdBitmapHeader指针

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

但是这在C中可以很容易地转换为lgLcdBitmap160x43x1lgLcdBitmapQVGAx32,但在c#中不是我该怎么做才能有效地将这两个结构体中的一个传递给函数?

指向C结构体第一个元素的指针与指向该结构体的指针相同.但不是c#:互操作问题

你应该声明extern函数的两个重载,它们接受两个不同的ref结构参数。