1

別の struct の固定サイズの配列を使用して、C# で struct をどのように宣言しますか? これが機能するように宣言する必要があります。または、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;
}

編集:私が学んだことは、RGBQUAD の 256 サイズの配列を割り当てる場合、 BITMAPINFOマーシャル サイズを常に 44 バイト イベントに保つことが重要でUnmanagedType.ByValArrayあるということです。SizeConst = 1

編集 2:ただし、SizeConst は実際の配列サイズよりも小さくしてはなりません。そうしないと、アンマネージ コードによってアプリがクラッシュする可能性があります。

4

2 に答える 2

3

コメントに記載されているように、C# では、構造体に構造体の固定サイズの配列を作成することはできません。

しかし、それはあなたが望むものではありません。宣言では

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

bmiColorsは固定長配列として宣言されていますが、実際には の可変長配列のプレース ホルダーですRGBQUAD。配列の実際の長さは、(少し複雑な方法で) の値に依存しますbmiHeader.biClrUsed

C# でこれを処理する方法は、構造体で何をしているかに完全に依存しますBITMAPINFO

アップデート

私はちょうどあなたの他の質問を見ました。を渡してBITMAPINFOおりSetDIBits、カラー テーブルには常に 256 のエントリがあります。したがって、 set の宣言では256にBITMAPINFO.bmiColors設定されます。SizeConst

于 2013-02-25T20:21:35.720 に答える
3

残念ながら (そして、.net の設計目的の 1 つが COM との相互運用を促進することであったことを考えると、やや驚くべきことですが)、.net ランタイムは、スタンドアロンSystem.Arrayオブジェクトまたは に組み込まれている文字配列以外の配列を理解していませんSystem.String。C# はfixed配列型を提供しますが、.net ランタイムが実際には理解せず、検証できない方法でポインター演算を使用して操作されます。

a0要素、a1a2などを含む構造体を定義し、switch ステートメントまたは他のそのような構造を使用してその要素にアクセスするインデックス付きプロパティを記述することにより、固定サイズの配列のように動作するものを作成することは可能ですが、そのような構造はおそらく通常の配列よりもはるかに遅く実行されます。

コードを使用する必要がない場合safe(そして、おそらく信頼されていない管理されたコードと相互運用しているという事実を考えると、「安全な」コードはおそらく考慮されません)、RGBQUAD明示的なレイアウトを使用して定義することをお勧めします。を他のデータとオーバーラップintさせ、他の構造にfixed int[whateverSize];RGB データを保持するための を含めます。そのインデックス付きアクセサーは、「int」メンバーを読み書きするだけでかなり効率的intに変換できるはずです。RGBQUAD

于 2013-02-26T16:33:13.727 に答える