Сериализация структуры, содержащей char * - PullRequest
2 голосов
/ 28 апреля 2010

Я получаю ошибку с сериализацией строки * char error C2228: left of '.serialize' must have class/struct/union Я мог бы использовать std :: string и затем получить из нее const char *. но мне нужна строка char *.

Ответы [ 3 ]

6 голосов
/ 28 апреля 2010

Сообщение об ошибке говорит само за себя, в сериализации Boost нет поддержки для сериализации указателей на примитивные типы.

Вы можете сделать что-то подобное в коде магазина:

int len = strlen(string) + 1;
ar & len;
ar & boost::serialization::make_binary_object(string, len);

и в коде загрузки:

int len;
ar & len;
string = new char[len]; //Don't forget to deallocate the old string
ar & boost::serialization::make_binary_object(string, len);
1 голос
/ 28 апреля 2010

Попробуйте это:

struct Example
{
  int i;
  char c;
  char * text; // Prefer std::string to char *

  void Serialize(std::ostream& output)
  {
     output << i << "\n";
     output << c << "\n";

     // Output the length of the text member,
     // followed by the actual text.
     size_t  text_length = 0;
     if (text)
     (
         text_length = strlen(text);
     }
     output << text_length << "\n";
     output << text << "\n";
  };

  void Input(std::istream& input)
  {
     input >> i;
     input.ignore(1000, '\n'); // Eat any characters after the integer.
     input >> c;
     input.ignore(1000, '\n');

     // Read the size of the text data.
     size_t  text_length = 0;
     input >> text_length;
     input.ignore(1000, '\n');
     delete[] text; // Destroy previous contents, if any.
     text = NULL;
     if (text_length)
     {
         text = new char[text_length];
         input.read(text, text_length);
     }
};

Поскольку указатели не являются переносимыми, вместо них должны быть записаны данные.

Текст известен как поле переменной длины . Поля переменной длины обычно выводятся (сериализуются) в двух структурах данных: длина, за которой следуют данные ИЛИ, за которыми следует символ терминала . Сначала указание длины позволяет использовать чтение блока . С последней структурой данных данные должны считываться по одной единице за раз, пока не будет прочитан символ терминала . Примечание: последняя структура данных также подразумевает, что символ терминала не может быть частью набора элементов данных.

Некоторые важные вопросы, которые следует учитывать при сериализации:
1. Используйте формат, который не зависит от платформы, например, текст ASCII для чисел.
2. Если метод платформы недоступен или не разрешен, определите для чисел точную спецификацию, включая Порядковый номер и максимальная длина .
3. Для чисел с плавающей запятой спецификация должна рассматривать компоненты числа с плавающей запятой как отдельные числа, которые должны соответствовать спецификации для числа (то есть экспоненты, величины и мантиссы).
4. Предпочитайте записи фиксированной длины записям переменной длины.
5. Предпочитаю сериализацию в буфер. Пользователи объекта могут затем создать буфер из одного или нескольких объектов и записать буфер как один блок (используя одну операцию). Аналогично для ввода.
6. Предпочитайте использовать базу данных для сериализации. Хотя это может быть невозможно для работы в сети, старайтесь изо всех сил иметь базу данных для управления данными. База данных может отправлять данные по сети.

1 голос
/ 28 апреля 2010

Нет способа сериализовать указатель на что-то в boost::serialization (я подозреваю, что фактического способа сделать это тоже нет). Указатель - это просто адрес памяти, эти адреса памяти обычно являются специфическими для экземпляра объекта, и, что действительно важно, этот адрес не содержит информации о том, где остановить сериализацию.

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

Первое и оптимальное решение для вашей проблемы - это обернуть ваш char*, используя std::string или вашу собственную строковую реализацию. Второе означало бы написание специальной подпрограммы сериализации для char* и, как я подозреваю, обычно будет делать то же самое, что и первый метод.

...