Если вы хотите, чтобы ваш код переносился между машинами с разным порядком байтов, вам нужно придерживаться использования одного порядка байтов в своих файлах. Всякий раз, когда вы читаете или записываете файлы, вы выполняете преобразование между порядком байтов хоста и порядком байтов файла. Обычно используется то, что вы называете сетевым порядком байтов, когда вы хотите записать файлы, переносимые на все машины. Сетевой порядок байтов определяется прямым порядком байтов, и есть готовые функции, предназначенные для обработки этих преобразований (хотя их очень легко написать самостоятельно).
Например, перед записью long в файл вы должны преобразовать его в сетевой порядок байтов с помощью htonl (), а при чтении из файла вы должны преобразовать его обратно в порядок байтов хоста с помощью ntohl (). В системе с прямым порядком байтов htonl () и ntohl () просто возвращают то же число, которое передано функции, но в системе с прямым порядком байтов они меняют местами каждый байт в переменной.
Если вы не заботитесь о поддержке систем с прямым порядком байтов, это не проблема, хотя это по-прежнему хорошая практика.
Еще одна важная вещь, на которую следует обратить внимание, - это заполнение ваших структур / классов, которые вы пишете, если вы записываете их непосредственно в файл (например, заголовок и строка). Разные компиляторы на разных платформах могут использовать разное заполнение, что означает, что переменные по-разному выравниваются в памяти. Это может серьезно сломать ситуацию, если компиляторы, которые вы используете на разных платформах, используют разные отступы. Поэтому для структур, которые вы собираетесь записывать непосредственно в файлы / другие потоки, вы всегда должны указывать отступы. Вы должны указать компилятору упаковать ваши структуры следующим образом:
#pragma pack(push, 1)
struct Header {
// This struct uses 1-byte padding
...
};
#pragma pack(pop)
Помните, что это сделает использование структуры более неэффективным, когда вы будете использовать ее в своем приложении, потому что доступ к невыровненным адресам памяти означает больше работы для системы. Вот почему обычно рекомендуется иметь отдельные типы для упакованных структур, которые вы пишете в потоки, и тип, который вы фактически используете в приложении (вы просто копируете элементы из одного в другой).
РЕДАКТИРОВАТЬ. Другой способ решить эту проблему, конечно же, - сериализовать эти структуры самостоятельно, что не потребует использования #pragma (прагмы зависят от компилятора, хотя все основные компиляторы, насколько мне известно, поддерживают пакет прагм).
person
reko_t
schedule
28.10.2009