Нужна помощь с файлом IO в C - PullRequest
1 голос
/ 02 июня 2011

Я преобразую следующий код из C # в C, и я не думаю, что я делаю это правильно.

Entry3D и entry_3d - это просто структуры, содержащие int lookup, length, extra воба случая.Вот фрагмент кода C # (и он прекрасно работает):

    BinaryReader reader = new BinaryReader(File.Open("artidx.mul", FileMode.Open));
    BinaryReader art = new BinaryReader(File.Open("art.mul", FileMode.Open));
    int count = (int)(reader.BaseStream.Length / 12);
    int length = 0x10000;
    Entry3D[] index = new Entry3D[length];
    Console.WriteLine("Loading indexes {0}", count);
    for (int i = 0; i < count && i < length; i++)
    {
        index[i].lookup = reader.ReadInt32();
        index[i].length = reader.ReadInt32();
        index[i].extra = reader.ReadInt32();
    }
    for (int i = count; i < length; ++i)
    {
        index[i].lookup = -1; 
        index[i].length = -1;
        index[i].extra = -1;
    }

Вот часть C, с которой у меня возникают проблемы.

/* Init everything else */
printf( "Init maps & gfx" );
mapFile = fopen( "sd:/map0.mul",   "rb" ), 
 artIdx = fopen( "sd:/artidx.mul", "rb" ),
    art = fopen( "sd:/art.mul",    "rb" );

if ( mapFile == NULL || artIdx == NULL || art == NULL )
{
  printf( "D'oh, file loading failed: [%d][%d][%d]", mapFile == NULL, artIdx == NULL, art == NULL  );
  return(1);
}

/* Find artidx count and set length */
printf( "Init art index" );
fseek( artIdx, 0, SEEK_END ); 
int count = (ftell(artIdx) / 12), length = 0x10000; // 0x10000 entries availible
entry_3d entries[length];
fseek( artIdx, 0, SEEK_SET );

printf( "Reading art-idx, count=%d", count );
int i;
for( i = 0; i < count && i < length; i++ )
{
  //printf( "loc: %u i: %u", ftell( artIdx ), i );
  //fread( &entries[i], 12, 1, artIdx );
  fread( &(entries[i].lookup), 4, 1, artIdx ); // read 12 bytes total
  fread( &(entries[i].length), 4, 1, artIdx );
  fread( &(entries[i].extra), 4, 1, artIdx );
}

printf( "Setting aidx remainders" );
for ( i = count; i < length; i++ )
{
  entries[i].lookup = -1; 
  entries[i].length = -1;
  entries[i].extra = -1;
}  

Для меня немного невозможноотладить часть C, но я могу сказать, что она «умирает» где-то в первом цикле for.Я предполагаю, что это возможно чтение после конца потока (даже если это не должно)?

Ответы [ 2 ]

3 голосов
/ 02 июня 2011

Я не вижу здесь много неправильного. Код будет правильно работать на Linux / Windows.

Обработка ошибок может быть улучшена.

Он не завершится с ошибкой, если файл artidx не кратен 12 байтам.

Полагаю, этому коду довольно легко не хватает памяти на консоли Wii. Попробуйте выделить массив entry_3d динамически (используя calloc / malloc). Также попробуйте уменьшить длину, чтобы убедиться, что у вас не хватает памяти. Не исключено, что реализация libc на Wii не предупредит вас, когда стек будет перекрывать кучу; Встраиваемые системы иногда предполагают, что программисты знают все тонкости и ограничения устройства (Wii с его множеством процессорных микросхем является отличным примером этого во многих отношениях, поэтому я действительно рассмотрю это).

Я почти уверен, что вы знаете, как найти форумы, на которых прячутся доморощенные разработчики. Они могли бы пролить свет здесь.

0 голосов
/ 02 июня 2011

Если у вас нет доступа к отладчику, вы можете добавить несколько операторов printf в цикл, чтобы увидеть, как далеко он продвинется до того, как умрет. Добавьте что-то вроде printf("i == %i\n", i); вверху каждой итерации цикла. Кроме того, сохраните возвращаемое значение fread в переменной и распечатайте его (для каждого вызова fread). Когда программа умирает, это должно как минимум оставить следы крошек, за которыми вы можете следить.

Кроме того, проверьте возвращаемое значение ваших вызовов fopen и fseek и убедитесь, что они вернулись успешно.

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