标签: cereal

谷物和Boost序列化是否使用零拷贝?

我已经在几个序列化协议之间进行了一些性能比较,包括FlatBuffers,Cap'n Proto,Boost序列化和谷物.所有测试都是用C++编写的.

我知道FlatBuffers和Cap'n Proto使用零拷贝.使用零拷贝时,序列化时间为空,但序列化对象的大小更大.

我认为谷物和Boost序列化没有使用零拷贝.但是,序列化时间(对于int和double)几乎为空,序列化对象的大小几乎与Cap'n Proto或Flatbuffers对象相同.我没有在他们的文件中找到任何有关零拷贝的信息.

谷物和Boost序列化也使用零拷贝吗?

c++ serialization boost copy cereal

16
推荐指数
1
解决办法
1068
查看次数

有没有办法使用Cereal/C++为std :: map指定更简单的JSON(de-)序列化?

我正在开发的项目是一个管理大量自定义硬件设备的C++应用程序.该应用程序具有客户端的套接字/端口接口(如GUI).每种设备类型都有自己定义良好的JSON模式,我们可以使用Cereal对这些模式进行序列化.

但该应用程序还需要解析来自客户端的入站JSON请求.请求的一部分指定设备过滤器参数,大致类似于SQL'WHERE'子句,其中所有表达式都是AND.例如:

"filter": { "type": "sensor", "status": "critical" }
Run Code Online (Sandbox Code Playgroud)

这将指示客户端想要在具有"关键"状态的每个"传感器"设备上执行操作.从表面上看,似乎过滤器参数的C++实现将是std :: map.但是当我们尝试使用Cereal反序列化它失败的对象时.当我们序列化硬编码的过滤器映射时,它看起来像这样:

"filter": [
   { "key": "type", "value": "sensor" },
   { "key": "status", "value": "critical" }
]
Run Code Online (Sandbox Code Playgroud)

现在我可以理解为什么Cereal支持这种详细的地图序列化.毕竟,地图的关键字可以是非字符串类型.但在这种情况下,键一个字符串.

我并不十分热衷于重写我们的界面规范,并让我们的客户生成明显非惯用的JSON,以满足Cereal.我是谷歌的新手,我们坚持这一点.有没有办法告诉Cereal将此过滤器解析为std :: map?或者我可能是错误的方式.是否还有其他一些我们应该反序列化的stl容器?

c++ serialization json stl cereal

9
推荐指数
1
解决办法
4309
查看次数

虚拟继承和多态:谷物库是否与对象布局混乱?

我有四个类(A,B,CD经典的金刚石图案和以下)Container含有类unique_ptr<A>.我想使用谷物序列化库序列化这些类.

struct A {int f1; int f2; int f3}

struct B : public virtual A {
    template<typename Archive>
    inline void save(Archive& ar) const {
        std::cerr << "Saving Obj: " << this << std::endl;
        std::cerr << "This: " << &(this->f1) << " " 
            << &(this->f2) << " " << &(this->f3) << std::endl;
        std::cerr << "This: " << this->f1 << " " 
            << this->f2 << " " << …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism inheritance cereal

6
推荐指数
1
解决办法
356
查看次数

C++ Cereal:序列化C风格的数组

可以/如何使用谷物库序列化数组.

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
}
Run Code Online (Sandbox Code Playgroud)

这不起作用(我也不期望它).也没有

ar(cereal::binary_data(data,l)); 
Run Code Online (Sandbox Code Playgroud)

(我认为它会工作,因为它看起来像一个人会使用的增强代码),这会产生编译错误:

/usr/local/include/cereal/cereal.hpp:79:17:注意:候选模板被忽略:替换失败:可变修改类型'unsigned char(&)[l]'不能用作模板参数BinaryData binary_data(T && data,size_t size)

也没有

ar.saveBinaryValue(data,l);
Run Code Online (Sandbox Code Playgroud)

由于该方法似乎只支持XML/Json,我想要一个二进制存档.

c++ cereal

5
推荐指数
1
解决办法
4017
查看次数

谷歌JSON输出错过了结束大括号

我正在使用Cereal C++ v1.1.1,类似于我正在尝试以下文档中给出的示例:

#include <sstream>
#include <iostream>
#include <cereal/archives/json.hpp>

int main() {
  std::ostringstream os;
  cereal::JSONOutputArchive archive(os);
  int x = 12;
  archive(CEREAL_NVP(x));
  std::cout << os.str(); // JUST FOR DEMONSTRATION!
}
Run Code Online (Sandbox Code Playgroud)

我希望有以下内容:

{
  "x":12
}
Run Code Online (Sandbox Code Playgroud)

但是结束的大括号丢失了.知道代码中缺少什么吗?

更新:

添加archive.finishNode()似乎解决了问题.但我会说这不是解决方案.根据operator()文档,调用操作符序列化输入参数,为什么要添加finishNode额外的?

c++ json cereal

5
推荐指数
1
解决办法
778
查看次数

如何使用谷物序列化boost :: ptr_vector?

是否可以boost::ptr_vector使用谷物序列化实例?如果是这样,怎么样?

c++ boost cereal

5
推荐指数
1
解决办法
708
查看次数

C++ CMake 编译错误(/usr/bin/ld:找不到 &lt;LIBRARY_NAME&gt;)

*我知道有很多关于此的问题,但在谈论 CMake 时它们根本没有多大帮助,因此我决定提出这个问题*

因此,我正在研究 CLion,它使用 CMake 来导入并向编译器提供参数,并成功包含(导入)位于名为“ExternalLibraries”的文件夹中的外部库(cereal:将类序列化为 json 文件)我的项目文件夹的根目录。它工作得很好,直到我重新启动 IDE 并尝试再次运行代码...它返回了编译错误(我认为)。

我的 CMake 文件如下所示:

cmake_minimum_required(VERSION 3.3)
project(xMemory)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

include_directories ("${PROJECT_SOURCE_DIR}/ExternalLibraries/cereal-1.1.2/include/")

set(SOURCE_FILES main.cpp xObject.cpp xObject.h)
add_executable(xMemory ${SOURCE_FILES})
target_link_libraries (xMemory cereal)
Run Code Online (Sandbox Code Playgroud)

当我尝试运行/编译时,shell 给了我这个:

/home/lunaticsoul/Documents/clion-1.2.4/bin/cmake/bin/cmake --build /home/lunaticsoul/.CLion12/system/cmake/generated/95701c38/95701c38/Debug0 --target xMemory -- -j 4
Scanning dependencies of target xMemory
[ 33%] Building CXX object CMakeFiles/xMemory.dir/xObject.cpp.o
[ 66%] Building CXX object CMakeFiles/xMemory.dir/main.cpp.o
[100%] Linking CXX executable xMemory
/usr/bin/ld: cannot find -lcereal
collect2: error: ld returned 1 exit status
make[3]: *** [xMemory] Error 1
make[2]: …
Run Code Online (Sandbox Code Playgroud)

c++ cmake cereal clion

5
推荐指数
2
解决办法
3万
查看次数

使用Cereal序列化库中的模板化多态类型

我有一个模板化的基类:

template<typename T>
class A {
    public:
    T a;

    template<class Archive>
    void serialize(Archive & ar) {
        ar(a);
    }
};
Run Code Online (Sandbox Code Playgroud)

以及从中派生的模板化类:

template<typename T>
class B : public A<T> {
    public:
    T b;

    template<class Archive>
    void serialize(Archive & ar) {
        ar(cereal::base_class<A<T>>(this));
        ar(b);
    }
};
Run Code Online (Sandbox Code Playgroud)

它在另一个序列化类中使用:

template<typename T>
class C {

    template<class Archive>
    void serialize(Archive & ar)
    {
        ar(collection);
    }

    std::vector<std::shared_ptr<A<T>>> collection;
};
Run Code Online (Sandbox Code Playgroud)

该代码和使用它的代码被编译成静态库

根据我对谷物文档的理解,我需要添加

CEREAL_REGISTER_TYPE(A<double>)
CEREAL_REGISTER_TYPE(A<float>)

CEREAL_REGISTER_TYPE(B<double>)
CEREAL_REGISTER_TYPE(B<float>)
Run Code Online (Sandbox Code Playgroud)

在每个类的头文件中,对于将要使用的每种类型等

这样编译。但是运行时错误为

尝试保存未注册的多态类型(B)。在调用CEREAL_REGISTER_TYPE之前,请确保您的类型已在CEREAL_REGISTER_TYPE中注册,并且已包含您正在使用的档案(并已在CEREAL_REGISTER_ARCHIVE中注册)。如果您的类型已经注册,但仍然看到此错误,则可能需要使用CEREAL_REGISTER_DYNAMIC_INIT。

从文档中,我认为我需要CEREAL_FORCE_DYNAMIC_INIT(libname)在标题和CEREAL_REGISTER_DYNAMIC_INITCPP文件中添加,但是没有cpp文件。或一个合适的CPP文件来放置它。

添加CEREAL_REGISTER_POLYMORPHIC_RELATION没有任何变化,因为B的序列化函数正在使用调用基函数A …

c++ templates cereal

5
推荐指数
1
解决办法
1147
查看次数

如何在编译时检测类型是否为shared_ptr

我希望得到一种模板化的方法来查找类型是否为shared_ptr,并且基于我希望有一个新的函数特化.

示例主要功能是,

template <class T> inline
void CEREAL_LOAD_FUNCTION_NAME( RelaxedJSONInputArchive & ar,    NameValuePair<T> & t )
{
    std::cout << " CEREAL_LOAD_FUNCTION_NAME NameValuePair 1 " << std::endl;
     ar.setNextName( t.name );
     ar( t.value );
}
Run Code Online (Sandbox Code Playgroud)

如果t.value是shared_ptr,那么我想要一个不同的函数特化.我试过下面,

template <class T> inline
typename std::enable_if<is_pointer<T>::value, void>::type
CEREAL_LOAD_FUNCTION_NAME( RelaxedJSONInputArchive & ar, NameValuePair<T> & t )
 {
    std::cout << " CEREAL_LOAD_FUNCTION_NAME NameValuePair 2 " << std::endl;
   ar.setNextName( t.name );
   ar( t.value );
  }
Run Code Online (Sandbox Code Playgroud)

但它似乎没有用.这些是c ++ 11谷物库的一部分.我正在尝试自定义.

c++ templates shared-ptr c++11 cereal

5
推荐指数
2
解决办法
2754
查看次数

std :: string_view的自定义序列化会导致意外的编译器错误

我已经在github上问了这个问题(大约一个月前),没有任何答案,所以我现在在这里问。

我在项目中使用Cereal作为序列化库。我尝试添加序列化功能std::string_view(基本上是从std::string实现中复制和粘贴)。但是,Cereal会引发编译器错误:

谷物找不到提供的类型和档案组合的任何输出序列化功能。

这是我的实现(我在这里禁用了反序列化,但是我也尝试了一个伪函数,它给了我相同的结果):

#pragma once

#include "../cereal.hpp"

#include <string_view>

namespace cereal
{
    //! Serialization for basic_string_view types, if binary data is supported
    template <class Archive, class CharT, class Traits>
    typename std::enable_if<traits::is_output_serializable<BinaryData<CharT>, Archive>::value, void>::type
    CEREAL_SAVE_FUNCTION_NAME(Archive& ar, std::basic_string_view<CharT, Traits> const& str)
    {
        // Save number of chars + the data
        ar(make_size_tag(static_cast<size_type>(str.size())));
        ar(binary_data(str.data(), str.size() * sizeof(CharT)));
    }


    //! Deserialization into std::basic_string_view is forbidden due to its properties as a view.
    //! However std::basic_string_view can be deserialized …
Run Code Online (Sandbox Code Playgroud)

c++ cereal c++17

5
推荐指数
1
解决办法
136
查看次数

标签 统计

c++ ×10

cereal ×10

boost ×2

json ×2

serialization ×2

templates ×2

c++11 ×1

c++17 ×1

clion ×1

cmake ×1

copy ×1

inheritance ×1

polymorphism ×1

shared-ptr ×1

stl ×1