Problem using Cereal to serialize

#1

Hi, I’m trying to use Cereal to serialize/unserialize data on json files. But somehow I can’t make it work. Anyone has experience with it?

// cereal types
#include <cereal/types/vector.hpp>
#include <cereal/types/string.hpp>
// for doing the actual serialization
#include <cereal/archives/json.hpp>

void ofApp::setup() {
    float b1;
    float b2;

    {
        std::ifstream f("data.json");
        cereal::JSONInputArchive ar(f);
        ar(CEREAL_NVP(b1), CEREAL_NVP(b2)); 
        // ofApp.cpp:59:9: error: no matching function for call to object 
        // of type 'cereal::JSONInputArchive'
        // cereal.hpp:617:21: note: candidate function template not viable: 
        // no known conversion from 'cereal::JSONInputArchive' 
        // to 'cereal::InputArchive<cereal::JSONInputArchive, 0>' for object argument
    }

    b1++;
    b2 = ofRandomuf();

    {
        std::ofstream f("data.json");
        cereal::JSONOutputArchive ar(f);
        ar(CEREAL_NVP(b1), CEREAL_NVP(b2));
        // ofApp.cpp:70:9: error: type 'cereal::JSONOutputArchive' 
        // does not provide a call operator
    }
}

I think my code looks similar to the json example at the bottom of https://uscilab.github.io/cereal/serialization_archives.html but there must be a difference I guess… what could it be?

#2

have you tried this ?

#3

Thank you! I added a JSON example at that addon

Which is very weird, because the addon is just a few includes and nothing else. I have two apparently equal projects: one based on ofxCereal, one where I imported the library directly. Same code. The second one doesn’t work.

I’ll post back if I figure out why.

Edit: I switched my non working project to use ofxCereal and it still didn’t work. When I deleted the cereal/ folder from inside src/ (I had placed the files there before I knew of ofxCereal) then suddenly the errors disappeared. It seems there was something it didn’t like about the folder structure.

1 Like
#4

By the way, I’m also building out json serialization with the build in ofJson (aka nlohman::json) here:

nlohman::json provides a really nice way to allow “automatic” serialization. See the tests for some examples. There are still a lot of classes / enumerations I haven’t added, but a lot of the main ones are there.

#5

looks nice!
anyway, how can we add OF types too?
something like:

struct SomeData {
    std::string name;
    std::vector<float> values;
    vector<ofColor> palette; // <- of type

is giving me:

Error:(462, 9) static_assert failed "cereal could not find any output serialization functions for the provided type and archive combination. \n\n Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n Serialize functions generally have the following signature: \n\n template \n void serialize(Archive & ar) \n { \n ar( member1, member2, member3 ); \n } \n\n "

Am I missing something?

There’s another add-on that includes an example with OF types:

Also, sometimes I have used this other add-on for that:

#6

@bakercp

I want to create a json settings/configuration structure that is serialized and automatically reloaded using inotify, so my “gui” becomes that json file: I tweak values in the json file and the program picks up changes and updates behavior accordingly.

Would any of ofxSerializer or ofxCereal be better than the other for this? I wonder which one requires less maintenance when I add or remove data to the json file…

@moebiussurfing

vector<ofColor> palette;

This https://uscilab.github.io/cereal/archive_specialization.html shows how to implement the serialization of map<string,string> so maybe this approach can be used to do the same with vector<ofColor>. In theory you can implement the serialization of anything, right? I haven’t tried though.

#7

This already works with ofxSerializer

        // Make vector.
        std::vector<ofColor> palette = { ofColor::red };
        // Serialize it.
        ofJson json = palette;
        // Save it.
        ofSaveJson("palette.json", json);

        // Load it.
        ofJson paletteJson = ofLoadJson("palette.json");

        // Deserialize.
        std::vector<ofColor> newPalette =  paletteJson;

        // Check it.
        std::cout << ofToString(newPalette) << std::endl;

1 Like
#8

All major data STL data structures are already implemented in nlohman::json. Then I implemented the ofColor and it figures it all out using argument dependent lookup (ADL). You just have to define the from_json and to_json for the data structure of interest in the same namespace as the data structure.

You can also save as bjson, mesgpack, etc. See the readme for more

#9

@hamoid this other addon has something about reloading, using ofxWatchFile:

#10

Thank you :slight_smile: ofxWatchFile keeps checking once per second if the file has changed so I wanted to give inotify a try. I have it now working at https://gitlab.com/hamoid/ofjsoninotify

Suggestions are welcome.

ps. inotify is Linux only.