指向C struct的第一个元素的指针与指向struct的指针相同。但不是在C#:Interop问题

时间:2011-09-25 14:05:29

标签: c# c interop

对不起标题,我有互操作问题。 我正在函数中使用的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语言中可以很容易地将其转换为 lgLcdBitmap160x43x1 lgLcdBitmapQVGAx32 ,但不能用于C# 如何有效地将这两个结构中的一个传递给函数?

1 个答案:

答案 0 :(得分:1)

您应该声明extern函数的两个重载,它们采用两个不同的ref结构参数。