Как получить байт [] в capnp :: Data

На официальном сайте есть хороший и относительно полный пример о том, как можно использовать CapnProto для сериализации C ++. Чего не хватает, так это как обрабатывать второй тип Blob capnp::Dataкак только capnp::Text покрыт.

Просто для полноты вот что говорит язык схемы о типе BLOB-объектов:

Blobs: текст, данные

  • Текст всегда в кодировке UTF-8 и завершается NUL.

  • Данные — это абсолютно произвольная последовательность байтов.

Итак, если у меня есть следующая схема

struct Tiding {
id @0 :Text;
payload @1 :Data;
}

Я могу начать строить свое сообщение, как это

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

tiding.setId("1");

В этот момент я застрял. Я не могу сделать это:

typedef unsigned char byte;

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

Так что я немного обошел вокруг и увидел, что capnp :: Data оборачивается kj::ArrayPtr<const byte>, но я не смог каким-то образом ArrayPtrтем более используйте его для установки поля Payload для моего сообщения.

Я видел, что есть способ установить значение по умолчанию для типа Data (Т.е. payload @5 :Data = 0x"a1 40 33";), но язык схемы в данном случае не переводится на C ++, так что это также не помогло мне.

Я был бы признателен, если бы кто-то мог указать, что мне здесь не хватает. Кроме того, как бы я это сделал, если бы я List(Data) вместо просто Data как полезная нагрузка в моей схеме?

0

Решение

kj::ArrayPtr принципиально пара указателя и размера.

Вы можете создать один, позвонив kj::arrayPtr(), который принимает два аргумента: указатель и размер массива. Пример:

byte buffer[256];
kj::ArrayPtr<byte> bufferPtr = kj::arrayPtr(buffer, sizeof(buffer));

kj::ArrayPtr имеет begin() а также end() методы, которые возвращают указатели, и size() метод. Таким образом, вы можете преобразовать обратно в указатель / размер, как:

byte* ptr = bufferPtr.begin();
size_t size = bufferPtr.size();

Собирая все это вместе, в вашем примере вы хотите:

tiding.setPayload(kj::arrayPtr(data, sizeof(data)));
4

Другие решения

Других решений пока нет …