具有另一个结构的固定大小数组的结构
本文关键字:结构 小数 数组 另一个 | 更新日期: 2023-09-27 18:00:55
如何在C#中用另一个结构的固定大小数组声明一个结构?我需要声明这一点,这样它才能工作。或者,如果我想要创建位图信息(-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;
}
编辑:我自己学到的是,如果我分配256大小的RGBQUAD数组,UnmanagedType.ByValArray
和SizeConst = 1
在保持BITMAPINFO封送大小恒定为44字节事件方面非常重要。
编辑2:但是SizeConst不能小于实际数组大小,否则非托管代码可能会导致应用程序崩溃。
不幸的是(鉴于.net的设计目标之一是促进与COM的互操作,IMHO有点令人惊讶(,.net运行时对任何类型的数组都不了解,除了独立的System.Array
对象或System.String
中内置的字符数组。尽管C#提供了fixed
数组类型,但这些类型是使用指针算术操作的,而.net运行时并不真正理解,也无法验证。
通过定义具有元素a0
、a1
、a2
等的结构,并编写索引属性,该索引属性使用switch语句或其他此类构造来访问其元素,可以创建行为类似于固定大小数组的东西,但此类构造的执行速度可能比普通数组慢得多。
如果您不需要使用safe
代码(并且考虑到您正在与可能不受信任的托管代码进行互操作,"安全"代码可能不是一个考虑因素(,我建议您使用显式布局定义RGBQUAD
,将int
与其他数据重叠,然后让其他结构包括fixed int[whateverSize];
来保存RGB数据。它的索引访问器应该能够通过读取/写入其"int"成员来非常有效地将int
转换为RGBQUAD
。
正如注释中所指出的,在C#中,您不能在结构中创建固定大小的结构数组。
但这不是你想要的。在申报中
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
CCD_ 15被声明为固定长度数组,但它实际上是CCD_ 16的可变长度数组的占位符。数组的实际长度取决于(以稍微复杂的方式(bmiHeader.biClrUsed
的值。
在C#中如何处理这个问题完全取决于您对BITMAPINFO
结构所做的操作。
更新
我刚刚看到你的另一个问题。您正在将BITMAPINFO
传递给SetDIBits
,并且您的颜色表总是有256个条目。因此,在BITMAPINFO.bmiColors
的声明中将SizeConst
设置为256。