2013-02-25 107 views
1

如何在C#中用另一个结构的固定大小的数组声明结构体?我需要this宣布,以便它的工作。或者,如果我想创建bitmapinfo(-header),我的方法错了吗?另一个结构的固定大小数组的结构

[StructLayout(LayoutKind.Sequential)] 
public struct RGBQUAD 
{ 
    public byte b; 
    public byte g; 
    public byte r; 
    public byte reserved; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct BITMAPINFO 
{ 
    public BITMAPINFOHEADER bmiHeader; 
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.LPStruct, SizeConst = 1)] 
    public RGBQUAD[] bmiColors; 
} 

编辑:我得知自己是UnmanagedType.ByValArraySizeConst = 1在这里很重要在44个字节的事件不断保持BITMAPINFO元帅的大小,如果我给你256 RGBQUAD的大小的数组。

编辑2:但SizeConst一定不能小于实际的数组大小,否则非托管代码可能会使应用程序崩溃。

+0

你不能声明一个固定大小的结构体,你只能声明一个结构体在interop期间如何被编组。 – 2013-02-25 16:38:18

+0

也许这会帮助吗? http://www.pinvoke.net/default.aspx/Structures/BITMAPINFOHEADER。html – 2013-02-25 16:39:46

回答

3

正如注释中所述,在C#中,您不能在结构中创建固定大小的结构数组。

但这不是你想要的。在申报

typedef struct tagBITMAPINFO { 
    BITMAPINFOHEADER bmiHeader; 
    RGBQUAD   bmiColors[1]; 
} BITMAPINFO, *PBITMAPINFO; 

bmiColors被声明为固定长度的阵列,但它确实对的RGBQUAD一个可变长度数组的占位符。数组的实际长度取决于(in a slightly complicated way)的值bmiHeader.biClrUsed

如何在C#中处理这个问题完全取决于您对BITMAPINFO结构所做的操作。

更新

我刚刚看到您的其他问题。您将BITMAPINFO传递给SetDIBits,并且您的颜色表始终有256个条目。所以在声明BITMAPINFO.bmiColors集合SizeConst设置为256.

+0

我需要一个适用于任何调色板大小的可重用解决方案。所以我想保持原始大小为1.这是否意味着我在这里的声明是正确的? – Bitterblue 2013-02-26 07:41:56

+0

将.Net中的结构编组为本机API时,实际上会复制数据。如果将SizeConst设置为1,则只有一个调色板条目会被复制。充其量,你的图像颜色将是错误的。最糟糕的是,SetDIBits在读取超过分配缓冲区的末尾时会崩溃。如果将其设置为256,则不必使用所有条目。 – arx 2013-02-26 14:06:48

+0

是的,这至少在CreatePalette上修复了崩溃。如果我没有256色但是16或8,我可以动态复制元帅吗? – Bitterblue 2013-02-26 14:22:31

3

不幸的是(和恕我直言有点令人惊讶的是,.net的设计目标之一是促进与COM互操作).net运行时不理解任何种类的数组除了独立的System.Array对象或内置到System.String中的字符数组。尽管C#提供了fixed数组类型,但是这些操作是使用指针算术以.net运行库不能真正理解和无法验证的方式进行的。

有可能创造一些通过定义与元件a0a1a2等一个结构和写入,其使用switch语句或其它这样的构建体,以它们的访问元素的索引属性的行为类似于固定大小的数组,但这样的结构可能比正常的数组执行速度慢得多。

如果您不需要使用safe代码(并且考虑到您正在与可能不受信任的托管代码进行互操作的事实,那么“安全”代码可能不是一个考虑因素)我建议您定义您的RGBQUAD使用显式布局,将int与其他数据重叠,然后让其他结构包含fixed int[whateverSize];来保存RGB数据。其索引访问器应该能够通过读取/写入其“int”成员而相当有效地将int转换为RGBQUAD

相关问题