82

C++ で記述されたライブラリを C# に変換していますが、キーワード 'union' が 1 回存在します。構造体で。

それをC#に翻訳する正しい方法は何ですか? そして、それは何をしますか?次のようになります。

struct Foo {
    float bar;

    union {
        int killroy;
        float fubar;
    } as;
}
4

6 に答える 6

89

そのために明示的なフィールド レイアウトを使用できます。

[StructLayout(LayoutKind.Explicit)] 
public struct SampleUnion
{
    [FieldOffset(0)] public float bar;
    [FieldOffset(4)] public int killroy;
    [FieldOffset(4)] public float fubar;
}

未テスト。アイデアは、2 つの変数が構造体で同じ位置にあるということです。もちろん、そのうちの 1 つしか使用できません。

構造体チュートリアルの共用体に関する詳細情報

于 2008-09-24T12:24:41.107 に答える
22

これがどのように使用されているかを知らずに、これに対処する方法を実際に決定することはできません。単にスペースを節約するために使用されている場合は、無視して構造体を使用できます。

ただし、ユニオンが使用される理由は通常ではありません。それらを使用する一般的な理由は 2 つあります。1 つは、同じデータにアクセスする方法を 2 つ以上提供することです。たとえば、int と 4 バイトの配列の結合は、32 ビット整数のバイトを分離する (多くの) 方法の 1 つです。

もう 1 つは、構造体のデータがネットワーク データ パケットなどの外部ソースから来た場合です。通常、共用体を囲む構造体の 1 つの要素は、有効な共用体のフレーバーを示す ID です。

これらのいずれの場合でも、union をやみくもに無視して、2 つ (またはそれ以上) のフィールドが一致しない構造体に変換することはできません。

于 2008-09-24T15:37:33.013 に答える
4

を使用してunion1 つの型のバイトを別の型にマップしている場合は、BitConverter代わりに C# を使用できます。

float fubar = 125f; 
int killroy = BitConverter.ToInt32(BitConverter.GetBytes(fubar), 0);

また;

int killroy = 125;
float fubar = BitConverter.ToSingle(BitConverter.GetBytes(killroy), 0);
于 2016-09-21T10:47:51.417 に答える
4

C/C++ では、共用体は同じメモリ位置に異なるメンバーをオーバーレイするために使用されるため、int と float の共​​用体がある場合、両方とも同じ 4 バイトのメモリを使用して格納し、明らかに一方に書き込むと他方が破損します ( int と float はビット レイアウトが異なります)。

.Net では、Microsoft はより安全な選択を行い、この機能を含めませんでした。

編集:相互運用を除く

于 2008-09-24T12:25:03.337 に答える
0

個人的には、UNION をまとめて無視し、Killroy と Fubar を別々のフィールドとして実装します。

public struct Foo
{
    float bar;
    int Kilroy;
    float Fubar;
}

UNION を使用すると、int によって割り当てられた 32 ビットのメモリが節約されます。最近では、アプリを作成または中断することはありません。

于 2008-09-24T12:34:54.920 に答える