Iam には、ID、SpellName、Category などのゲーム内で使用可能なスペル データを含む、ゲームのデータベース ファイルである DBC ファイルがあります。構造体は次のようなものです。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct SpellEntry
{
public uint ID;
public uint Category;
public float speed;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.I4)]
public int[] Reagent;
public int EquippedItemClass;
[MarshalAs(UnmanagedType.LPStr)] // Crash here
public string SpellName;
}
バイナリリーダーでファイルを読み取り、それを構造体にマーシャリングしています。スニペット:
binReader.BaseStream.Seek(DBCFile.HEADER_SIZE + (index * 4 * 234), SeekOrigin.Begin);
buff = binReader.ReadBytes(buff.Length);
GCHandle handdle = GCHandle.Alloc(buff, GCHandleType.Pinned);
Spell.SpellEntry testspell = (Spell.SpellEntry)Marshal.PtrToStructure(handdle.AddrOfPinnedObject(), typeof(Spell.SpellEntry));
handdle.Free();
さらに複雑にするために、SpellName などの文字列を DBC ファイルに格納する方法を見てみましょう。レコードではなく、文字列はファイルの末尾の「文字列テーブル」ブロックに含まれています。レコード内の文字列データには、文字列テーブル内の文字列に対する数値 (オフセット) が含まれています。(実際には文字列ではありません)。
文字列ブロック (ファイルの最後) から文字列 [] まで、すべての文字列を読み取ることができました。(これはレコードの読み取りを開始する前ではありません)次に、レコードの読み取りを開始しますが、最初の問題は次のとおりです。
1.) 構造体の最後の行で「クラッシュ」するため、読み取ることができません (実際には文字列ではないため) 2.) 文字列を数値に割り当てることができません。
読むと数字になるのですが、結果として、その文字列を、文字列テーブルの数字が指し示す SpellName に代入する必要があります。ああ。