支持所有常用編程語
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