Cap'n Proto C++ 序列化为 char 数组(或任何字节数组)
Cap’n Proto C++ serialize to char array (or any byte array)
我的目标是通过 MPI 发送序列化数据。我已经使用 ProtoBuf 完成了此操作,但我想尝试使用更快的序列化方法,例如 Cap'n Proto(我也会尝试其他方法,但在这里我被卡住了)。对于 ProtoBuf,我使用函数 SerializeToArray(void * data, int size)
函数,它工作得很好。
现在,我想用 Cap'n Proto 做同样的事情,但我找不到任何方法(如果你有 link 请发送)。由于 Cap'n Proto 声称是 ProtoBuf 的更快替代品,我觉得这令人惊讶。也许,我正在以完全错误的方式解决这个问题。
所以我的问题变成了:
如何使用 Cap'n Proto 序列化为 char 数组(或任何字节数组)(如果可能的话)?或者我如何以一种可以使用 C++ 通过 MPI 轻松发送的方式进行序列化?
我不确定这是否是最有效的方法,但它确实有效。
messages.capnp 文件:
@0xf46c6bd8234dfab9;
struct Testmessage {
string @0 :Text;
float @1 :Float32;
int @2 :Int32;
}
run_cap_n_proto.cpp 文件:
#include <iostream>
#include <capnp/serialize.h>
#include "messages.capnp.h"
int main()
{
// Encode message
::capnp::MallocMessageBuilder message_builder;
Testmessage::Builder message = message_builder.initRoot<Testmessage>();
message.setString( "string" );
message.setFloat( 3.14 );
message.setInt( 1337 );
auto encoded_array = capnp::messageToFlatArray(message_builder);
auto encoded_array_ptr = encoded_array.asChars();
auto encoded_char_array = encoded_array_ptr.begin();
auto size = encoded_array_ptr.size();
// Send message
// Receive message
// Decode message
auto received_array = kj::ArrayPtr<capnp::word>(reinterpret_cast<capnp::word*>(encoded_char_array), size/sizeof(capnp::word));
::capnp::FlatArrayMessageReader message_receiver_builder(received_array);
auto message_receiver = message_receiver_builder.getRoot<Testmessage>();
auto s_r = message_receiver.getString().cStr();
auto f_r = message_receiver.getFloat();
auto i_r = message_receiver.getInt();
std::cout << "received: " << s_r << ", " << f_r << ", " << i_r << std::endl;
}
编译messages.capnp
:
$ capnp compile -oc++ messages.capnp
编译主程序:
$ g++ -o run_cap_n_proto run_cap_n_proto.cpp messages.capnp.c++ `pkg-config --cflags --libs capnp`
对于文档中 AddrssBook example 中给出的消息,您可以这样做:
// Documentation: https://capnproto.org/cxx.html
// AddressBook example
void sendMessage( const char* data, const std::size_t size );
void writeAddressBook()
{
::capnp::MallocMessageBuilder message;
auto addressBook = message.initRoot<AddressBook>();
auto people = addressBook.initPeople(1);
auto alice = people[0];
alice.setId(123);
alice.setName("Alice");
alice.setEmail("alice@example.com");
auto alicePhones = alice.initPhones(1);
alicePhones[0].setNumber("555-1212");
alicePhones[0].setType(Person::PhoneNumber::Type::MOBILE);
alice.getEmployment().setSchool("MIT");
// get char array and send
const auto m = capnp::messageToFlatArray( message );
const auto c = m.asChars();
std::cout << c.size() << '\n';
sendMessage( c.begin(), c.size() ); // pass as char array
}
我的目标是通过 MPI 发送序列化数据。我已经使用 ProtoBuf 完成了此操作,但我想尝试使用更快的序列化方法,例如 Cap'n Proto(我也会尝试其他方法,但在这里我被卡住了)。对于 ProtoBuf,我使用函数 SerializeToArray(void * data, int size)
函数,它工作得很好。
现在,我想用 Cap'n Proto 做同样的事情,但我找不到任何方法(如果你有 link 请发送)。由于 Cap'n Proto 声称是 ProtoBuf 的更快替代品,我觉得这令人惊讶。也许,我正在以完全错误的方式解决这个问题。
所以我的问题变成了:
如何使用 Cap'n Proto 序列化为 char 数组(或任何字节数组)(如果可能的话)?或者我如何以一种可以使用 C++ 通过 MPI 轻松发送的方式进行序列化?
我不确定这是否是最有效的方法,但它确实有效。
messages.capnp 文件:
@0xf46c6bd8234dfab9;
struct Testmessage {
string @0 :Text;
float @1 :Float32;
int @2 :Int32;
}
run_cap_n_proto.cpp 文件:
#include <iostream>
#include <capnp/serialize.h>
#include "messages.capnp.h"
int main()
{
// Encode message
::capnp::MallocMessageBuilder message_builder;
Testmessage::Builder message = message_builder.initRoot<Testmessage>();
message.setString( "string" );
message.setFloat( 3.14 );
message.setInt( 1337 );
auto encoded_array = capnp::messageToFlatArray(message_builder);
auto encoded_array_ptr = encoded_array.asChars();
auto encoded_char_array = encoded_array_ptr.begin();
auto size = encoded_array_ptr.size();
// Send message
// Receive message
// Decode message
auto received_array = kj::ArrayPtr<capnp::word>(reinterpret_cast<capnp::word*>(encoded_char_array), size/sizeof(capnp::word));
::capnp::FlatArrayMessageReader message_receiver_builder(received_array);
auto message_receiver = message_receiver_builder.getRoot<Testmessage>();
auto s_r = message_receiver.getString().cStr();
auto f_r = message_receiver.getFloat();
auto i_r = message_receiver.getInt();
std::cout << "received: " << s_r << ", " << f_r << ", " << i_r << std::endl;
}
编译messages.capnp
:
$ capnp compile -oc++ messages.capnp
编译主程序:
$ g++ -o run_cap_n_proto run_cap_n_proto.cpp messages.capnp.c++ `pkg-config --cflags --libs capnp`
对于文档中 AddrssBook example 中给出的消息,您可以这样做:
// Documentation: https://capnproto.org/cxx.html
// AddressBook example
void sendMessage( const char* data, const std::size_t size );
void writeAddressBook()
{
::capnp::MallocMessageBuilder message;
auto addressBook = message.initRoot<AddressBook>();
auto people = addressBook.initPeople(1);
auto alice = people[0];
alice.setId(123);
alice.setName("Alice");
alice.setEmail("alice@example.com");
auto alicePhones = alice.initPhones(1);
alicePhones[0].setNumber("555-1212");
alicePhones[0].setType(Person::PhoneNumber::Type::MOBILE);
alice.getEmployment().setSchool("MIT");
// get char array and send
const auto m = capnp::messageToFlatArray( message );
const auto c = m.asChars();
std::cout << c.size() << '\n';
sendMessage( c.begin(), c.size() ); // pass as char array
}