У меня две структуры, а первая - как список во втором:
struct SType{
int Num;
char Word[20];
char sugg[20];
};
struct DataPktType
{
list<SType> MyList;
char filename[MAX_SIZE];
int numslaves;
};
Я знаю, что для сериализации есть ускорение и библиотека google, но я хочу отправить эти данные на специальный сервер, который не позволяет устанавливать boost и т.д.
Поэтому я должен сделать это вручную. Я видел и протестировал простой ответ на этом веб-сайте для сериализации и десериализации вручную qaru.site/questions/687440/.... По мере того как я испытал это работает отлично с собственной структурой. Тем не менее, это для простой структуры, и, как вы видели, у меня есть список во второй структуре. список имеет разный размер времени.
Я ценю, если кто-нибудь может показать какой-то пример или намек. В настоящее время я отправляю struct over socket таким образом, что вызвало ошибку сегментации!
// Write and read a message to/from the server
write(Sockfd, (char*)&DataPkt, sizeof(DataPktType));
read(Sockfd, (char*)&recDataPkt, sizeof(DataPktType));
Я "вручную" сделал что-то похожее на то, что, как я подозреваю, вы хотите сделать.
Для непростого типа (DataPktType) вы можете рассмотреть следующий грубый контур (только для того, чтобы помочь вам начать работу).
Во-первых, я добавил 2 виртуальных метода ко всем классам, которые должны были участвовать - в моем случае мы назвали их хранением и восстановлением. Эти методы касались только атрибутов данных их собственного класса.
restore() был, в некотором смысле, обратным для store().
struct SType{
int Num;
char Word[20];
char sugg[20];
virtual void store(ostream& os);
virtual void restore(istream& is);
};
struct DataPktType
{
list<SType> MyList;
char filename[MAX_SIZE];
int numslaves;
virtual void store(ostream& os);
virtual void restore(istream& is);
};
Итак, где DataPktType.store() может передавать каждый атрибут данных POD в поток:
DataPktType::store(ostream& os)
{
os << MyList.size(); // gotta know how many to extract later
for (auto it = myList.begin(); myList.end(); it++)
{
it->store(os); // tell the SType to store itself at this point in the stream
}
os << filename;
os << numslaves;
}
Тогда "обратный" может быть чем-то вроде
DataPktType::restore(istream& is)
{
size_t listSize = 0;
is >> listSize;
// input error checks
for(size_t i=0; i<listSize; ++i)
{
SType listItem;
listItem.restore(is); // assumes the list item contents are 'next' in the file
MyList.push_back(listItem); // I don't use std::list often,
// there seems to be several choices for adding to a list
}
is >> filename;
is >> numslaves;
}
Это те вещи, которые, я думаю, вам нужно делать.
Обратите внимание, что указатели не входят в потоки.
Обратите внимание, что симметрия не идеальна, но вам нужно будет выяснить, как обращаться с каждым действием.
В моих усилиях, я считаю, я добавил несколько простых проверок на этом пути...
Кроме того, моя команда использовала текст для первой реализации. Как человек, это будет намного легче отлаживать, и вы можете использовать редактор для отладки проблем "симметрии".
Кроме того, вы можете обнаружить, что производительность ввода-вывода текста является достаточной и, таким образом, просто оставить ее как текст.
У нас были некоторые сжатые сроки, и в конечном итоге он выбрал двоичный код ввода-вывода. Но мы просто проверяли текст ввода-вывода.
Удачи.
PS - мы в конце концов добавили номер версии для содержимого store/restore, чтобы поддерживать изменения структуры во время эволюции кода проекта.
list<SType>
), никогда не будет работать. И почему тег C на этот вопрос? Вы должны отправлять байты, так или иначе, а не указатели на платформе. Этого не избежать. Что еще хуже, вы также должны учитывать платформенность ваших многобайтовых интегралов. Все это является частью магии использования механики консервированных сериализаций, таких как boost и google protobuffs.