如何将 byte[] 放入 capnp::Data

Dav*_*ave 0 c++ c++11 capnproto

在官方网站上,有一个很好且相对全面的示例,说明如何使用 CapnProto 进行 C++ 序列化。缺少的是如何处理第二个 Blob 类型capnp::Data,因为只capnp::Text涉及到。

为了完整起见,这里是架构语言关于 blob 类型的说明:

Blob:文本、数据

...

  • 文本始终采用 UTF-8 编码并以 NUL 结尾。

  • 数据是完全任意的字节序列。

所以,如果我有以下架构

struct Tiding {
    id @0 :Text;
    payload @1 :Data;
}
Run Code Online (Sandbox Code Playgroud)

我可以像这样开始构建我的消息

::capnp::MallocMessageBuilder message;
Tiding::Builder tiding = message.initRoot<Tiding>();

tiding.setId("1");
Run Code Online (Sandbox Code Playgroud)

在这一点上,我被卡住了。我不能这样做:

typedef unsigned char byte;

byte data[100];
... //populate the array
tiding.setPayload(data)
//error: no viable conversion from 'byte [100]' to '::capnp::Data::Reader'
Run Code Online (Sandbox Code Playgroud)

所以我四处乱逛,看到 capnp::Data 正在包装kj::ArrayPtr<const byte>,但我无法以某种方式获得ArrayPtr,更不用说使用它来设置我的消息的 Payload 字段了。

我看到有一种方法可以为类型Data(即payload @5 :Data = 0x"a1 40 33";)设置默认值,但在这种情况下,模式语言并没有真正转换为 C++,所以这也没有帮助我。

如果有人能指出我在这里遗漏了什么,我将不胜感激。另外,如果我有List(Data)而不是Data作为模式中的有效负载,我将如何做到这一点?

Ken*_*rda 5

Akj::ArrayPtr基本上是一对指针和大小。

您可以通过调用 来创建一个kj::arrayPtr(),它接受两个参数:一个指针和数组大小。例子:

byte buffer[256];
kj::ArrayPtr<byte> bufferPtr = kj::arrayPtr(buffer, sizeof(buffer));
Run Code Online (Sandbox Code Playgroud)

kj::ArrayPtr具有begin()end()其返回指针的方法,和一个size()方法。所以你可以转换回指针/大小,如:

byte* ptr = bufferPtr.begin();
size_t size = bufferPtr.size();
Run Code Online (Sandbox Code Playgroud)

将它们放在一起,在您的示例中,您需要:

tiding.setPayload(kj::arrayPtr(data, sizeof(data)));
Run Code Online (Sandbox Code Playgroud)