C++ Cereal: serialize C-style array
Asked Answered
A

1

5

Can/How do you serialize an array using the cereal library.

I.e.

void save(Archive & ar, const unsigned int version) const
{
    unsigned int l  = g1_size_bin(g,POINT_COMPRESS);
    uint8_t data[l];
    memset(data, 0, l);
    g1_write_bin(data, l, g,POINT_COMPRESS);
    ar(l);
    ar(data); // what should be here
}

That doesn't work (nor would I expect it too). Nor does

ar(cereal::binary_data(data,l)); 

(which I would think would work, since it looks like the boost code one would use), which produces a compilation error :

/usr/local/include/cereal/cereal.hpp:79:17: note: candidate template ignored: substitution failure : variably modified type 'unsigned char (&)[l]' cannot be used as a template argument BinaryData binary_data( T && data, size_t size )

Nor does

ar.saveBinaryValue(data,l);

Since that method only appears to be supported for XML/Json and I want a binary archive.

Alongshore answered 17/12, 2014 at 4:52 Comment(0)
S
11

cereal::binary_data is the correct construct to use in this case assuming you want a binary representation of the POD array. This will only work for archives that support binary_data (binary and portable_binary). binary_data doesn't work for the text based archives because it is seen as an optimization for a more generic serialization method - see how vector is serialized for an example of this.

Anyway, here's a working example of serializing a C style array:

#include <cereal/archives/binary.hpp>
#include <iostream>

int main()
{
  std::stringstream ss;

  {
    cereal::BinaryOutputArchive ar(ss);
    std::uint8_t data[] = {1, 2, 3};
    ar( cereal::binary_data( data, sizeof(std::uint8_t) * 3 ) );
  }

  {
    cereal::BinaryInputArchive ar(ss);
    std::uint8_t data[3];
    ar( cereal::binary_data( data, sizeof(std::uint8_t) * 3 ) );

    for( int i : data )
      std::cout << i << " ";
  }

  return 0;
}

If you wanted to serialize a C style array to a text based archive, or if your array wasn't over POD types, you would need to iterate over each object and serialize it individually.

Speedway answered 2/1, 2015 at 22:24 Comment(5)
I have an array (on heap) that contains N structs of 2x doubles inside (x and y) Should I iterate each for serialization ?Statist
This code will look more nicely if you rename ar to a.Panatella
I was searching for another thing related to serialization and cereal, and I came across this answer. I have a question though. ss only has std::ios_base::in | std::ios_base::out mode by default. will it not create problem? shouldn't it have std::ios_base::binary open mode?Coridon
@ArdaAytekin You are correct - to be safe (and unfortunately much more verbose), std::ios_base::binary should be supplied along with the appropriate in or out flags.Speedway
Cereal is great. But it's such a shame different archives provide different interfaces. Now my code needs to know the archive type. Is there a unified interface?Gonzalez

© 2022 - 2024 — McMap. All rights reserved.