POCO C ++ объект в сериализацию строки JSON - PullRequest
0 голосов
/ 21 сентября 2018

Интересно, как можно сериализовать объект данного класса (например, Person) с его атрибутами (например, name, age) в строку JSON, используя библиотеки POCO C ++.

Может быть, я должен создать свои модели, используя Poco :: Dynamic и Poco :: Dynamic :: Var, чтобы использовать POCO :: JSON :: Stringifier?Я не представляю, как это сделать ...

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

см. https://stackoverflow.com/a/52738109/5845104

#include <x2struct.hpp>  // include this header file

struct Person {
    std::string name;
    int age;
    XTOSTRUCT(O(name, age));  // add XTOSTRUCT at the end of struct define
}

int main(int argc, char *argv[]) {
    Person p;
    p.name = "Jack";
    p.age = 30;
    std::string json_str = x2struct::X::tojson(e); // call tojson to convert object ot json string
    return 0
}
0 голосов
/ 21 сентября 2018

В отличие от Java или C #, C ++ не имеет функции самоанализа / отражения вне информации о типе времени выполнения (RTTI), которая имеет различную направленность и ограничена полиморфными объектами.Это означает, что за пределами нестандартного прекомпилятора вы должны будете так или иначе сообщить платформе сериализации, как структурирован ваш объект и как вы в конечном итоге хотели бы отобразить его в иерархию int, std::stringи другие основные типы данных.Я обычно различаю три разных подхода: прекомпилятор, встроенная спецификация, преобразование свойств.

  1. Прекомпилятор. Хорошим примером прекомпиляторного подхода является буфер протокола Google: https://developers.google.com/protocol-buffers/docs/cpptutorial. Вы определяете свои сущности в отдельном файле .proto, который преобразуется с помощью проприетарного компилятора в .c и .h классы сущностей.Эти классы могут использоваться как обычные объекты POCO и могут быть сериализованы с использованием буферов протокола.

  2. Встроенная спецификация: Повышенная сериализация (https://www.boost.org/doc/libs/1_67_0/libs/serialization/doc/index.html), s11n (www.s11n.net) иrestc-cpp (https://github.com/jgaa/restc-cpp) - примеры явного указания структуры ваших POCO для каркаса внутри вашего собственного кода. API для этого может быть более или менее сложным, но принцип, лежащий в основе этого, всегда один и тот же:Вы предоставляете реализации serialise / deserialise для своих классов или регистрируете информацию метаданных, которая позволяет платформе генерировать их. Пример ниже от restc-cpp:

struct Post {
    int userId = 0;
    int id = 0;
    string title;
    string body;
};

BOOST_FUSION_ADAPT_STRUCT(
    Post,
    (int, userId)
    (int, id)
    (string, title)
    (string, body)
)
Преобразование свойств: последний вид сериализации, о котором я не хочу пропустить, это явное преобразование в промежуточный тип данных, предоставляемый платформой.Хорошие примеры этого подхода - дерево свойств повышения (https://www.boost.org/doc/libs/1_67_0/doc/html/property_tree.html) и JsonCpp (http://open -source-parsers.github.io / jsoncpp-docs / doxygen / index.html ).отвечает за реализацию преобразования ваших собственных типов в ptree, который Boost может сериализовать в любой формат, который вам нравится (XML, JSON).

Имея свой опыт работы со всеми тремя подходамив C ++ я бы по умолчанию порекомендовал вариант 3. Похоже, что он хорошо соответствует модели POCO C ++ Parser и Var для JSON. Одним из вариантов является то, что все классы POCO вашей сущности реализуют to_var или from_varили вы можете сохранить эти функции сериализации в отдельном пространстве имен для каждого класса POCO, так что их нужно включать только при необходимости.

Если вы работаете над проектами, для которых сериализуется значительное количество объектов (например, сообщения в коммуникационных библиотеках), опция предварительной компиляции может стоить первоначальной установки и дополнительной сложности сборки, но это зависит, каквсегда, о конкретном проекте, с которым вы имеете дело.

...