Проблема теории чтения структуры - PullRequest
0 голосов
/ 23 ноября 2010

У Iam есть DBC-файл, который является файлом базы данных для игры и содержит внутриигровые данные заклинаний, такие как ID, SpellName, Категория и т. Д. Структура выглядит примерно так:

    [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;
    }

Iamчтение файла с помощью бинарного ридера и его преобразование в структуру.Фрагмент:

                    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();

Теперь, чтобы быть более сложным, давайте посмотрим, как в файле DBC хранятся строки, например, SpellName.Его нет в записях, строки содержатся в конце файла, в блоке «таблица строк».Строковые данные в записях содержат номер (смещение) строки в таблице строк.(так что на самом деле это не строка).

Мне удалось прочитать все строки из блока строк (в конце файла) в строку [].(это не до начала чтения записей). Тогда я бы начал читать записи, но первая проблема:

1.) Я не могу прочитать его, потому что он «вылетает» в последней строкемоя структура (потому что на самом деле это не строка) 2.) Я не могу присвоить строку числу.

Когда я ее прочту, это будет число, но в конце, в результатеЯ должен назначить эту строку для SpellName, которая указана номером, в таблице строк.Боже .

1 Ответ

1 голос
/ 23 ноября 2010
public struct SpellEntry
{
    //...
    private int SpellNameOffset;
    public string SpellName {
        get { return Mumble.GetString(SpellNameOffset); }
    }
}

Это трудно понять правильно, Mumble должен быть статическим классом, поскольку вы не можете добавлять членов в SpellEntry.Это облажает Marshal.SizeOf (), делая его слишком большим.Вам нужно будет инициализировать Mumble, чтобы его статический метод GetString () мог обращаться к таблице строк.Перемещение свойства SpellName в другой класс решает проблему, но делает код тоже уродливым.

Это может сильно вас запутать.Если у вас есть версия, которая использует BitConverter, то вам определенно лучше использовать ее.Отделение формата файла от формата времени выполнения на самом деле является преимуществом здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...