支持所有常用编程语
https://capnproto.org/
GitHub - capnproto/capnproto: Cap'n Proto serialization/RPC system - core tools and C++ library
https://capnproto.org/capnproto-c++-win32-1.0.2.zip
常用命令:
capnp help
capnp compile -oc++ myschema.capnp
capnp decode myschema.capnp MyType < message.bin > message.txt
capnp encode myschema.capnp MyType < message.txt > message.bin
capnp eval myschema.capnp myConstant
myschema.capnp:
@0xa8712255ec118b18;
struct Person {
id @0 :UInt32;
name @1 :Text;
email @2 :Text;
phones @3 :List(PhoneNumber);
struct PhoneNumber {
number @0 :Text;
type @1 :Type;
enum Type {
mobile @0;
home @1;
work @2;
}
}
employment :union {
unemployed @4 :Void;
employer @5 :Text;
school @6 :Text;
selfEmployed @7 :Void;
# We assume that a person is only one of these.
}
}
struct AddressBook {
people @0 :List(Person);
}
示例代码:
#include "myschema.capnp.h"
#include <capnp/message.h>
#include <capnp/serialize-packed.h>
#include <iostream>
void writeAddressBook(int fd) {
::capnp::MallocMessageBuilder message;
AddressBook::Builder addressBook = message.initRoot<AddressBook>();
::capnp::List<Person>::Builder people = addressBook.initPeople(2);
Person::Builder alice = people[0];
alice.setId(123);
alice.setName("Alice");
alice.setEmail("alice@example.com");
// Type shown for explanation purposes; normally you'd use auto.
::capnp::List<Person::PhoneNumber>::Builder alicePhones =
alice.initPhones(1);
alicePhones[0].setNumber("555-1212");
alicePhones[0].setType(Person::PhoneNumber::Type::MOBILE);
alice.getEmployment().setSchool("MIT");
Person::Builder bob = people[1];
bob.setId(456);
bob.setName("Bob");
bob.setEmail("bob@example.com");
auto bobPhones = bob.initPhones(2);
bobPhones[0].setNumber("555-4567");
bobPhones[0].setType(Person::PhoneNumber::Type::HOME);
bobPhones[1].setNumber("555-7654");
bobPhones[1].setType(Person::PhoneNumber::Type::WORK);
bob.getEmployment().setUnemployed();
writePackedMessageToFd(fd, message);
}
void printAddressBook(int fd) {
::capnp::PackedFdMessageReader message(fd);
AddressBook::Reader addressBook = message.getRoot<AddressBook>();
for (Person::Reader person : addressBook.getPeople()) {
std::cout << person.getName().cStr() << ": "
<< person.getEmail().cStr() << std::endl;
for (Person::PhoneNumber::Reader phone : person.getPhones()) {
const char* typeName = "UNKNOWN";
switch (phone.getType()) {
case Person::PhoneNumber::Type::MOBILE: typeName = "mobile"; break;
case Person::PhoneNumber::Type::HOME: typeName = "home"; break;
case Person::PhoneNumber::Type::WORK: typeName = "work"; break;
}
std::cout << " " << typeName << " phone: "
<< phone.getNumber().cStr() << std::endl;
}
Person::Employment::Reader employment = person.getEmployment();
switch (employment.which()) {
case Person::Employment::UNEMPLOYED:
std::cout << " unemployed" << std::endl;
break;
case Person::Employment::EMPLOYER:
std::cout << " employer: "
<< employment.getEmployer().cStr() << std::endl;
break;
case Person::Employment::SCHOOL:
std::cout << " student at: "
<< employment.getSchool().cStr() << std::endl;
break;
case Person::Employment::SELF_EMPLOYED:
std::cout << " self-employed" << std::endl;
break;
}
}
}
void test() {
auto file = fopen("example.bin", "wt+");
if (!file)
return;
int fd = fileno(file); //如果是W+ 这里文件被清空的影响
writeAddressBook(fd);
fclose(file);
fflush(file);
file = fopen("example.bin", "rb+");
fd = fileno(file);
printAddressBook(fd);
fclose(file);
}
运行输出:
Alice: alice@example.com
mobile phone: 555-1212
student at: MIT
Bob: bob@example.com
home phone: 555-4567
work phone: 555-7654
unemployed
其它类似参考:
GitHub - protocolbuffers/protobuf: Protocol Buffers - Google's data interchange format
evanw (Evan Wallace) · GitHub