Портирование кода сериализации данных из С++ linux/mac в окна С++

У меня есть программная среда, скомпилированная и успешно работающая как на mac, так и на linux. Теперь я пытаюсь перенести его в окна (используя mingw). Пока у меня есть программное обеспечение, которое компилируется и работает под окнами, но оно неизбежно приводит к ошибкам. В частности, у меня есть проблема с чтением данных, которые были сериализованы в macos (или linux) в версии Windows программы (segfaults).

Процесс сериализации сериализует на примитиве значения примитивных переменных (longs, ints, ****** и т.д.).

Это код, который я использую:

#include <iostream>
#include <fstream>
template <class t="">
void serializeVariable(T var, std::ofstream &outFile)
{ outFile.write (reinterpret_cast < char *>(&var),sizeof (var));
}
template <class t="">
void readSerializedVariable(T &var, std::ifstream &inFile)
{
inFile.read (reinterpret_cast < char *>(&var),sizeof (var));
}
</class></class></fstream></iostream>

Итак, чтобы сохранить состояние пучка переменных, я вызываю serializeVariable для каждой переменной по очереди. Затем, чтобы прочитать данные, вызовы будут прочитаныSerializedVariable в том же порядке, в котором они были сохранены. Например, чтобы сохранить:

::serializeVariable<float>(spreadx,outFile);
::serializeVariable<int>(objectDensity,outFile);
::serializeVariable<int>(popSize,outFile);
</int></int></float>

И читать:

::readSerializedVariable<float>(spreadx,inFile);
::readSerializedVariable<int>(objectDensity,inFile);
::readSerializedVariable<int>(popSize,inFile);
</int></int></float>

Но в окнах это чтение сериализованных данных терпит неудачу. Я предполагаю, что окна сериализуют данные несколько иначе. Интересно, есть ли способ изменить этот код, чтобы данные, сохраненные на любой платформе, могли быть прочитаны на любой другой платформе... любые идеи?

Приветствия,

Бен.

4 ответа

Двоичная сериализация, подобная этой, должна хорошо работать на этих платформах. Вы должны соблюдать честь, но это тривиально. Я не думаю, что у этих трех платформ есть конфликты в этом отношении.

Однако вы действительно не можете использовать как свободные спецификации типов, когда вы это делаете. Размеры int, float, size_t могут меняться на разных платформах.

Для целых типов используйте типы строгого размера, найденные в заголовке cstdint. ********, int32_t и т.д. Windows не имеет доступного заголовка iirc, но вместо этого вы можете использовать boost/cstdint.hpp.

Плавающая точка должна работать, поскольку большинство компиляторов следуют тем же спецификациям IEEE.

C - Сериализация чисел с плавающей запятой (поплавки, удвоения)

Для двоичной сериализации действительно требуется тщательное модульное тестирование. Я бы настоятельно рекомендовал инвестировать время.


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

Например, я нашел этот код кода в msdn:

int isLittleEndian() { long int testInt = 0x12345678; char *pMem; pMem = (char *) testInt; if (pMem[0] == 0x78) return(1); else return(0);
}

Я думаю, у вас будут разные результаты в linux vs windows. Лучшим случаем было бы, если для вашего компилятора (ов) есть опция флага для использования одного формата или другого. Просто установите его на всех машинах одинаковыми.

Надеюсь, это поможет, Alex


Еще одно дикое предположение: вы забыли открытый файл в режиме двоичного чтения и потоках файлов Windows конвертировать последовательность 13,10-10.


Считаете ли вы использование сериализационных библиотек или форматов, например, например:

  • XDR (поддерживается libc) или ASN1
  • s11n (библиотека сериализации С++)
  • Json, очень простой текстовый формат со многими библиотеками для него, например. JsonCpp, Jansson, Jaula,....)
  • YAML, более мощный текстовый формат со многими библиотеками
  • или даже XML, который часто используется для целей сериализации...

(И для сериализации скаляров, htonl и вспомогательные процедуры должны помочь)

licensed under cc by-sa 3.0 with attribution.