如何序列化自定义类型?

问题描述 投票:0回答:1

我正在尝试使用 GridGain C++ 瘦客户端从用 C++ 编写的项目访问 GridGain 服务器:https://ignite.apache.org/docs/latest/thin-clients/cpp-thin-client 只要我使用基本类型(整数、std::string 等),一切都可以正常工作。 然而,更复杂的类型(任何类型的“结构”)需要序列化。序列化概述如下:https://ignite.apache.org/docs/latest/cpp-specific/cpp-serialization。该页面似乎提供了代码片段,但不是完整的示例。如果我尝试从该页面复制并编译代码:

class Address
{
  friend struct ignite::binary::BinaryType<Address>;
public:
  Address() { }

  Address(const std::string& street, int32_t zip) :
  street(street), zip(zip) { }

  const std::string& GetStreet() const
  {
    return street;
  }

  int32_t GetZip() const
  {
    return zip;
  }

private:
  std::string street;
  int32_t zip;
};

template<>
struct ignite::binary::BinaryType<Address>
{
  static int32_t GetTypeId()
  {
    return GetBinaryStringHashCode("Address");
  }

  static void GetTypeName(std::string& name)
  {
    name = "Address";
  }

  static int32_t GetFieldId(const char* name)
  {
    return GetBinaryStringHashCode(name);
  }

  static bool IsNull(const Address& obj)
  {
    return obj.GetZip() && !obj.GetStreet().empty();
  }

  static void GetNull(Address& dst)
  {
    dst = Address();
  }

  static void Write(BinaryWriter& writer, const Address& obj)
  {
    writer.WriteString("street", obj.GetStreet());
    writer.WriteInt32("zip", obj.GetZip());
  }

  static void Read(BinaryReader& reader, Address& dst)
  {
    dst.street = reader.ReadString("street");
    dst.zip = reader.ReadInt32("zip");
  }
};

它给出编译错误:

\ggainserializer.h(75): 错误 C2027: 使用未定义类型 'ignite::binary::BinaryReader' \install\gridgain\include\ignite\impl inary inary_reader_impl.h(46): 注意:参见 'ignite::binary::BinaryReader' 的声明 \ggainserializer.h(76): 错误 C2027: 使用未定义类型 'ignite::binary::BinaryReader' \install\gridgain\include\ignite\impl inary inary_reader_impl.h(46): 注意:参见 'ignite::binary::BinaryReader' 的声明 4>GGainSerializer.cpp ...

API是基于模板的,似乎缺少一些东西。

有人能够实现自定义 C++ 类型的序列化工作吗? ?如果是这样,请提供一段使用自定义类型序列化器 – C++“struct”-ures 写入和读取 Ignite(或相同的 GridGain)的示例代码。理想情况下,该代码应该是完整的,以便我可以编译它并逐步执行(调试)。 谢谢。

我们再次尝试按照此处的说明进行操作https://ignite.apache.org/docs/latest/cpp-specific/cpp-serialization但它们似乎不起作用。

ignite gridgain
1个回答
0
投票

非常感谢您的链接!查看它以及存储库中的其他文件,我终于能够完成 GridGain/Ignite 自定义类型序列化工作。我花了一周的时间才到达这里,所以将概述我所面临的问题和解决方案,因为它可能会帮助其他人:

  1. 我能找到的关于自定义类型的 C++ 序列化的唯一官方 Ignite/GridGain 文档是:https://ignite.apache.org/docs/latest/cpp-specific/cpp-serialization。不幸的是,如果没有引用您善意提供的存储库中的那些代码示例。在我看来,这些样本是关键。

  2. 上述文档中的代码存在错误,导致 GridGain 服务器抛出异常。

    static bool IsNull(const Address& obj) { return obj.GetZip() && !obj.GetStreet().empty(); }

应该是:

return !(obj.GetZip() && !obj.GetStreet().empty());
  1. 您提供的链接(https://github.com/apache/ignite/blob/master/modules/platforms/cpp/examples/put-get-example/src/put_get_example.cpp)引用文件这里:https://github.com/apache/ignite/tree/master/modules/platforms/cpp/examples/include/ignite/examples(特别是“ignite/examples/organization.h”)。这 3 个文件包含不同的标头,目前尚不清楚客户端代码中需要哪个标头。因此,在我的代码中显然我包含了导致编译问题的不同标头。必须包含的正确标头是“ignite/binary/binary.h”。不幸的是,上面(1)中提到的文档也没有明确说明这一点。
  2. 由于我使用 C++ 瘦客户端,最好的例子实际上是 https://github.com/apache/ignite/blob/master/modules/platforms/cpp/examples/thin-client-put-get-example/src /thin_client_put_get_example.cpp,但是您提供的链接也有很大帮助。

由于您显然是 Ignite 团队的成员(根据您在上述 Git 存储库中的提交),请澄清以下内容来帮助我们:

  1. 您是否知道 GridGain/Ignite 文档的良好链接,该文档概述了 C++ 瘦客户端和胖客户端功能以及最重要的 API 之间的差异?如果有的话,请提供,因为我找不到。
  2. 上面许多示例中使用的 BinaryTypeDefaultAll 基类的目的是什么?我找到的唯一文档https://ignite.apache.org/releases/latest/cppdoc/structignite_1_1binary_1_1BinaryTypeDefaultAll.html并没有说明太多。
  3. 对于 BinaryType 类,您能否解释一下方法的需求: a) GetTypeName() 。有没有办法以编程方式提取相同的名称? b) GetTypeId() 。同样,有没有办法以编程方式提取相同的名称? c) IsNull() 。根据我的测试,如果此方法在cache.put()操作期间返回true,服务器(或C++客户端)会抛出异常,拒绝持久化对象(值)。 同样,该类/API的唯一可用文档https://ignite.apache.org/releases/latest/cppdoc/structignite_1_1binary_1_1BinaryType_3_01T_01_5_01_4.html似乎没有解释太多。

诚挚抱歉问了这么多问题。 C++ 文档似乎不完整。因此,如果无法深入挖掘 Ignite/GridGain 代码,唯一的选择就是询问 Ignite 团队成员或支持人员。

再次非常感谢您!

© www.soinside.com 2019 - 2024. All rights reserved.