指向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中可以很容易地转换为lgLcdBitmap160x43x1或lgLcdBitmapQVGAx32,但在c#中不是我该怎么做才能有效地将这两个结构体中的一个传递给函数?
你应该声明extern
函数的两个重载,它们接受两个不同的ref
结构参数。