DOBON.NET DOBON.NETプログラミング掲示板過去ログ

配列を含む共用体

環境/言語:[VB.NET, C#]
分類:[.NET]

配列を含んだ構造体(共用体)で、FieldOffset属性で
配置を指定したいのですが、うまくいきません。
構造体を生成後、配列にはnewでメモリを割り当ててます。

以下のような例外が発生します。
>オフセット 0 に不適切に整列されたか、オブジェクト以外のフィールドでオーバーラップされたオブジェクト フィールドが含まれています。

byte[]に読み込んだデータを構造体にキャストしたいです。
現状は、仕方ないのでマーシャラでコピーしています。

うまい方法はないでしょうか?


[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)]
public byte[] buffer;
[FieldOffset(0)]
public MyStruct s; // MyStructをintなどに置き換えても一緒でした
}
■No12328に返信(KJさんの記事)
> 配列を含んだ構造体(共用体)で、FieldOffset属性で
> 配置を指定したいのですが、うまくいきません。

配列型の変数は、配列オブジェクトの参照を格納しているだけの、いわばポイ
ンタです。型の宣言に、相互運用のための属性を指定しても、前述の事実は変
わりません。

MyUnion 型のメモリ配置のイメージを、C 言語風の擬似コードで表現すると、

union MyUnion
{
    byte *buffer ;
    MyStruct s ;
}

です。仮に例外が発生しなくても、意図した処理は行えませんよね。

> byte[]に読み込んだデータを構造体にキャストしたいです。

unsafe コンテキストでなら、ポインタ型の変数を使って、C 言語風にキャス
トできるはずですよ。

byte[] buffer = new byte[...] ;
int foo ;

unsafe {fixed (byte* p = buffer) {
    MyStruct* myStruct = (MyStruct*)p ;
    foo = myStruct->bar ;
}}
> union MyUnion
> {
> byte *buffer ;
> MyStruct s ;
> }

union MyUnion
{
byte buffer[16];
MyStruct s;
}
こうできたらいいんですけどねー。

実は、MyStruct自体が配列を含んでいるので、
unsafeでもキャストできませんでした。

仕方ないので、おとなしくコピーします。
こういうときは、アンマネージコードが恋しくなります。
解決済み!
  • 題名: Re[3]: 配列を含む共用体
  • 著者: おおた
  • 日時: 2005/08/27 8:23:57
  • ID: 12383
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
■No12380に返信(KJさんの記事)
> 実は、MyStruct自体が配列を含んでいるので、
> unsafeでもキャストできませんでした。

フィールドのオフセットを指定する方法を使って、埋め込まれた配列を擬似的
に表現できたと思います。

[StructLayout(LayoutKind.Explicit, Size = 84)]
struct MyStruct
{
    [FieldOffset(0)] public int foo ; // foo[10]
    [FieldOffset(40)] public int bar ;
    [FieldOffset(44)] public int zot ; // zot[10]
}

foo = (&(myStruct->foo))[0] ;
bar = myStruct->bar ;
zot = (&(myStruct->zot))[9] ;
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板