将内部带有字节数组的结构传递给互操作方法 [英] Passing a struct with a byte array inside to a interop-ed method
问题描述
我遇到的情况是必须将结构传递给C方法(在我的C#文件中声明为extern).
I have a situation where I have to pass a struct to a C method (declared as extern in my C# file).
但是,此结构非常复杂.我已经在AllocHGlobal中成功使用了该方法,但是我想了解是否有可能通过仅传递对该结构的引用来使其以这种方式工作.
This struct however is quite complicated. I already used successfully the approach with AllocHGlobal, but I would like to understand if is possible to make it works in this way, by only passing a reference to the struct.
[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处存在一个对象,该对象未正确对齐或与另一个对象重叠.
The biggest problem is that I have to wrap everything in a union (the lgLcdBitmap struct). Actually C# is complaning because there is an object at offset 0 that is not correctly aligned or overlaps another object.
我认为问题与我的字节数组没有实际大小(仅使用SizeConst声明的大小)有关. 因为我不想使用固定的代码(这迫使我使用不安全的代码),所以我想了解如何解决此问题.
I think that the problem is connected with the fact that my byte array doesn't have a real size (only the one declared with SizeConst). Because I don't want to use fixed (it forces me to use unsafe code), I would like to understand how can I solve this.
我能想到的唯一想法是声明Size(在StructLayout内部)以允许C#理解我的结构是什么大小,但是我不确定它是否可以工作.
The only idea that I can think about is declaring Size (inside StructLayout) to allow C# understand what size is my struct, but I'm not sure it will works.
我要调用的方法是这个:
The method I have to call is this one:
public extern static uint lgLcdUpdateBitmap([In] int device, [In] ref lgLcdBitmap bitmap, [In] Priorities priority);
关于如何使一切正常工作的任何建议?
Any suggestion on how make everything works?
推荐答案
由于您不想使用fixed
,因此最好将字节数组声明为IntPtr
,分配给AllocHGlobal
,并使用填充数据Marshal.Copy
.无法使用MarshalAs
让P/调用编组执行所需的操作.
Since you don't want to use fixed
, your byte arrays are best declared as IntPtr
, allocated with AllocHGlobal
and filled with data using Marshal.Copy
. There's no way to get the P/invoke marshaller to do what you need using MarshalAs
.
这篇关于将内部带有字节数组的结构传递给互操作方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!