Поэтому я пишу программу для записи структуры в файл, а затем другую для чтения указанной структуры. Если структура была:
struct MODEL
{
FLOAT X, Y, Z;
D3DXVECTOR3 Normal;
FLOAT U, V;
};
struct RETURNTYPE
{
float vsize, isize;
MODEL* model;
DWORD* index;
}; //actual out structure
будут ли методы на http://courses.cs.vt.edu/cs2604/fall01/binio.html означать, что они будут записаны в этом порядке и будут ли они считаны в этом порядке?
Не обязательно, нет. Примеры, приведенные на странице (по крайней мере, бит, которые я читаю/просматриваю) опасны, потому что вы сбрасываете необработанную память на диск, а затем читаете ее. Это не очень хорошая практика.
Вкратце: спецификации языка C и C++ не оговаривают макет памяти структур, на самом деле существуют собственные языковые расширения, которые позволяют разработчику определять выравнивание, заполнение и другие детали структур, по этой причине приведенный ниже код не переносится между компиляторами (или даже обязательно версиями одного и того же компилятора, если какое-либо поведение должно быть изменено).
Кроме того, приведенный пример работает только для структур, содержащих типы значений; значения указателя или ссылочные типы не имеют смысла при сериализации из памяти на диск, если у вас есть такая структура:
struct Foo {
char* someString;
};
Затем он будет сериализован на диск как целое число, которое может быть 32-битным или 64-битным в зависимости от платформы, и это целое означает ничего, потому что адрес памяти ничего не значит на диске, особенно после процесса, который его написал закончилось.
Здесь еще одна проблема: на 68k и PowerPC (и других платформах с большими терминами) целые числа будут поменяны по байтам по сравнению с x86/x64, которые являются малоконтинентальными, что делает тот же самый код C/C++ генерирующим несовместимые файлы на разных платформах, Вот почему многие файлы не были совместимы между Mac OS и IBM PC/Windows в 1990-х годах, вам нужно было инвестировать в "программное обеспечение конвертера", которое знало, какие поля переустанавливают байтовый заказ.
Во всяком случае, лучший способ писать сложные типы на диск - это написать свой собственный метод сериализации, который имеет другие преимущества, такие как самодокументация файлового формата. Вот так:
struct Foo {
private:
int foo;
public:
void serialize(ostream& stream) {
stream.write( htonl( foo ) ); // htonl converts integers to big-endian order
}
void deserialize(istream& stream) {
stream.read( &foo, sizeof(int) );
foo = ntohl( foo ); // convert from big-endian back to native byte-order
}
};