私はstackoverflowに不慣れで、C#構造体とそのレイアウトについて質問があります。
次の構造体を想定しましょう。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct Link
{
// some primitive data (2 integers for example)
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public unsafe struct Node
{
[FieldOffset(0)]
public int LinkCount;
[FieldOffset(4)]
public Link* Links;
[FieldOffset(4)]
private fixed byte _linksData[10 * sizeof(Link)];
}
その理由は、IO-Performanceにはblittableタイプが必要だからです。サイズが数GBの非常に大きな(そしてノードごとに最大10個のリンクがまばらな)グラフを処理する必要があります。グラフは、ノード構造体の配列として表されます。上記のような設定で、たとえばグラフファイルからバイトポインタ(もちろんバイトバッファを指す)に100 MBを読み取って、Node*タイプのポインタにキャストできることを望んでいました。非常に良いパフォーマンス。最初、私のNode-structには、Link型の10個の個別の変数(Link0、...、Link10)があり、問題なく機能していました。ただし、これをコンパイル時に構成可能にすると、上記のNode-structが発生します。
私は、Linksが同じFieldOffsetを持っているので、_linksDataと同じメモリ位置を指すことを望んでいました。しかし実際には、リンクポインタは常にnullポインタです。
だから私の質問は:Linksが_linksDataと同じメモリ位置を指す方法はありますか、それとも構造体の固定サイズの配列を別の構造体に埋め込む別の方法がありますか?
事前にすべての回答をありがとう-Markus
Ben Voigtの投稿を読んだ後、構造体をクラスに変更することなく、同様のことを試しました。以下は私にとってそれがどのように機能するかです:
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public unsafe struct Node
{
[FieldOffset(0)]
public int LinkCount;
[FieldOffset(4)]
private fixed byte _linksData[10 * sizeof(Link)];
public Link* GetLinks()
{
fixed(byte* pLinksData = _linksData)
{
return (Link*)pLinksData;
}
}
}