На официальном сайте есть хороший и относительно полный пример о том, как можно использовать 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
как полезная нагрузка в моей схеме?
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)));
Других решений пока нет …