Serializing a struct containing char *

I am getting an error with serializing a char * string error C2228: left of '.serialize' must have class/struct/union

. I could use std :: string and then get const char * from it. but I need a char * string.

+2


source to share


3 answers


The error message says it all, there is no support in forcing serialization to serialize pointers to primitive types.

You can do something like this in your store code:

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

      



and in the download code:

int len;
ar & len;
string = new char[len]; //Don't forget to deallocate the old string
ar & boost::serialization::make_binary_object(string, len);

      

+6


source


There is no way to serialize a pointer to something in boost::serialization

(I suspect there is no real way to do this). A pointer is just a memory address, these memory addresses are usually object specific, and what is really important, this address does not contain information where to stop serialization.

You can't just tell your serializer, "Hey, take something from this pointer and serialize it. I don't care what size it has, just do it ..."



First, and the optimal solution for your problem is wrapping char*

with std::string

or your own implementation of the string. The second will mean writing a special serialization routine for char*

, and I suspect will usually do the same as the first method.

+1


source


Try the following:

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);
     }
};

      

Since pointers are not portable, data must be written instead.

The text is known as a variable length field . Variable length fields are typically outputted (serialized) into two data structures: length followed by data OR data followed by a terminal character. Specifying the length first allows block read to be used. With the latter data structure, data must be read one at a time until a terminal character is read. Note: The latter data structure also implies that the terminal character cannot be part of a data set.

Some important issues for serialization:
1. Use a platform independent format such as ASCII text for numbers.
2. If platform method is not available or allowed, define an exact specification for numbers, including Endianness and maximum length.
3. For floating point numbers, the specification must treat the components of the floating point number as separate numbers, which must conform to the specification for the number (ie, exponent, magnitude, and mantissa).
4. Prefer fixed-length records over variable-length records.
5. Suppose serialization to a buffer. Object users can then buffer one or more objects and write the buffer as one block (using one operation). Likewise for input.
6. Prefer to use a database for serialization. ... While this may not be possible for networking, try your best to keep the database in control of the data. The database can send data over the network.

+1


source







All Articles