簡體   English   中英

指向C結構的第一個元素的指針與指向該結構的指針相同。 但不是在C#中:互操作性問題

[英]Pointer to first element of C struct is the same as pointer to the struct. But not in C#: Interop problem

對不起,標題,我遇到互操作問題。 我在函數中使用的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#中則不能,該如何有效地將這兩個結構之一傳遞給函數?

您應該聲明extern兩個不同的ref struct參數的extern函數的兩個重載。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM