Я пытаюсь следить за статьей, написанной по адресу https://accu.org/index.php/journals/2317 Мне показалось это интересным теперь, когда я пытаюсь погрузиться в сериализацию / сохранение / загрузку файлов для некоторых административных инструментов. работа над. Я пометил его на c ++, потому что я перенесу его в класс после того, как заставлю его работать (надеюсь, с вашей помощью). библиотека на данный момент. Я хочу знать или попытаться выяснить, работают ли эти вещи. с memcpy.
Прямо сейчас он компилируется, но когда я сериализую и десериализую структуры, данные не совпадают.
Пожалуйста, просмотрите и помогите мне, или укажите на меня справа направление. После кода я постараюсь объяснить, как я это понимаю.
#include <iostream>
#include <cassert>
struct Y
{
int yy;
};
struct X
{
int xx;
struct Y* y = nullptr;
int z;
};
// Changed OutMemStram and InMemStream for IOMemStream, same data
struct IOMemStream
{
// changed from uint8_t* to char*
char* pp;
char* ppEnd;
};
// Output
inline void WriteToStream( IOMemStream* dst, void* p, size_t sz )
{
dst->pp = (char*)p; // original code doesn't contain this line
dst->ppEnd = (char*)p + sz; // original code doesn't contain this line
assert( (dst->pp + sz) <= dst->ppEnd );
memcpy( dst->pp, p, sz );
dst->pp += sz;
}
void SerializeX( IOMemStream* dst, X* x )
{
WriteToStream( dst, x, sizeof( X ) );
WriteToStream( dst, x->y, sizeof( Y ) );
}
// Input
inline void ReadFromStream( IOMemStream* src, void* p, size_t sz )
{
//assert( (src->pp + sz) <= src->ppEnd );
memcpy( p, src->pp, sz );
src->pp += sz;
}
void DeserializeX( IOMemStream* src, X* x )
{
ReadFromStream( src, x, sizeof( X ) );
// x->y contains garbage at this point(!)
// ok, not exactly garbage - but a pointer
// which is utterly invalid in our current space
x->y = new Y;
assert( x->y );
ReadFromStream( src, x->y, sizeof( Y ) );
}
// Usage sample
int main()
{
// Assume struct x was previously filled by other function
X x;
x.xx = 1000;
x.z = 2000;
x.y = new Y;
x.y->yy = 3000;
// IO buffer
IOMemStream ioms;
// Test for output
SerializeX( &ioms, &x );
// Test for input
X x1;
DeserializeX( &ioms, &x1 );
// x1.xx should be 1000 and x1.< should be 2000
std::cout << x1.xx << ", " << x1.z << std::endl;
delete x.y;
delete x1.y;
//delete ioms.pp; // gets exception
std::cin.get();
return 0;
}
Так я понял (или не понял).
- Struct X, содержит 2 целых числа и 1 указатель структуры на структуру Y, которая при условии, что int size = 4, размер X будет 12 байтов. Y это 4 байта.
- IOMemStream содержит указатели как на структуру X, так и на структуру Y.
- IOMemStream-> pp и IOMemStream-> ppEnd должны иметь 12 байтов и 4 байта из структуры X и X -> Y.
- Функция WriteToStream упаковывает байты из структур в указатели pp и ppEnd, после назначения X указатель увеличивается на размер, чтобы подготовиться к структуре Y. (в исходной статье утверждение сделано без присвоения переменных pp и ppEnd из
- IOMemStream) Функция SerializeX использует WriteToStrea как для структур X, так и для Y.
Почти то же самое для десериализации но в обратном порядке и ReadFromStream выделит память для структуры Y.
Я потерялся отсюда, поскольку значения не совпадают с сериализацией и десериализацией. Также, надеюсь, я правильно понял: D
Заранее спасибо!