当前位置: 首页 > news >正文

国企单位网站建设方案广东的网站建设

国企单位网站建设方案,广东的网站建设,具有价值的做网站,wordpress添加广告Protobuf使用 目录 proto3的更新定义协议格式编译protobufprotobuf_API 枚举和嵌套类标准消息方法解析和序列化 写一条消息阅读消息编译Protobuf扩展优化高级用法 proto3的更新 在第一行非空白非注释行#xff0c;必须写#xff1a; syntax proto3;字段规…Protobuf使用 目录 proto3的更新定义协议格式编译protobufprotobuf_API 枚举和嵌套类标准消息方法解析和序列化 写一条消息阅读消息编译Protobuf扩展优化高级用法 proto3的更新 在第一行非空白非注释行必须写 syntax proto3;字段规则移除了 required并把 optional 改名为 singular; 在 proto2 中 required 也是不推荐使用的。proto3 直接从语法层面上移除了 required规则。其实可以做的更彻底把所有字段规则描述都撤销原来的repeated 改为在类型或字段名后加一对中括号。这样是不是更简洁 repeated字段默认采用 packed 编码; 在 proto2 中需要明确使用 [packedtrue] 来为字段指定比较紧凑的 packed 编码方式。 移除了default 选项; 在 proto2 中可以使用 default 选项为某一字段指定默认值。在 proto3 中字段的默认值只能根据字段类型由系统决定。也就是说默认值全部是约定好的而不再提供指定默认值的语法。 在字段被设置为默认值的时候该字段不会被序列化。这样可以节省空间提高效率。 但这样就无法区分某字段是根本没赋值还是赋值了默认值。这在 proto3 中问题不大但在 proto2 中会有问题。 比如在更新协议的时候使用 default 选项为某个字段指定了一个与原来不同的默认值旧代码获取到的该字段的值会与新代码不一样。 枚举类型的第一个字段必须为 0 ; 移除了对分组的支持; 分组的功能完全可以用消息嵌套的方式来实现并且更清晰。在 proto2 中已经把分组语法标注为『过期』了。这次也算清理垃圾了。 移除了对扩展的支持新增了 Any 类型; Any 类型是用来替代 proto2 中的扩展的。目前还在开发中。 proto2 中的扩展特性很像 Swift 语言中的扩展。理解起来有点困难使用起来更是会带来不少混乱。 相比之下proto3 中新增的 Any 类型有点像 C/C 中的 void* 好理解使用起来逻辑也更清晰。 增加了 JSON 映射特性; 语言的活力来自于与时俱进。当前JSON 的流行有其充分的理由。很多『现代化』的语言都内置了对 JSON 的支持比如 Go、PHP 等。而 C 这种看似包罗万象的学院派语言因循守旧、故步自封以致于现出了式微的苗头。 map支持 mapkey_type, value_type map_field N; example: mapstring, Project projects 3;定义协议格式 .proto文件中的定义很简单为要序列化的每个数据结构添加消息然后为消息中的每个字段指定名称和类型。这是.proto定义您的消息的文件addressbook.proto。 (好的.proto文件命名风格是packagename.messagename.proto) syntax proto3;package tutorial;message Person {string name 1;int32 id 2;string email 3;enum PhoneType {MOBILE 0;HOME 1;WORK 2;}message PhoneNumber {string number 1;PhoneType type 2;}repeated PhoneNumber phones 4; }message AddressBook {repeated Person people 1; } 该.proto文件以包声明开头这有助于防止不同项目之间的命名冲突。在C中生成的类将放在与包名匹配的命名空间中。 每个元素上的“ 1”“ 2”标记标识该字段在二进制编码中使用的唯一“标记”。标签号1-15需要少于一个字节来编码而不是更高的数字因此作为优化您可以决定将这些标签用于常用或重复的元素将标签16和更高版本留给不太常用的可选元素。重复字段中的每个元素都需要重新编码标记号因此重复字段特别适合此优化。 必须使用以下修饰符之一注释每个字段 required(proto3中移除)必须提供该字段的值否则该消息将被视为“未初始化”。如果libprotobuf在调试模式下编译则序列化未初始化的消息将导致断言失败。在优化的构建中将跳过检查并始终写入消息。但是解析未初始化的消息将始终失败通过false从解析方法返回。除此之外必填字段的行为与可选字段完全相同。 optional(proto3中为singular)该字段可能已设置也可能未设置。如果未设置可选字段值则使用默认值。对于简单类型您可以指定自己的默认值就像我们type在示例中为电话号码所做的那样。否则使用系统默认值数字类型为0字符串为空字符串bools为false。对于嵌入式消息默认值始终是消息的“默认实例”或“原型”其中没有设置其字段。调用访问器以获取尚未显式设置的可选或必需字段的值始终返回该字段的默认值。 repeated(proto3默认采用 packed 编码)该字段可以重复任意次数包括零。重复值的顺序将保留在协议缓冲区中。将重复字段视为动态大小的数组。 proto3 中移除了default选项:字段的默认值只能根据字段类型由系统决定。也就是说默认值全部是约定好的而不再提供指定默认值的语法。在字段被设置为默认值的时候该字段不会被序列化。这样可以节省空间提高效率。 编译protobuf 现在运行编译器指定源目录应用程序的源代码所在的位置 - 如果不提​​供值则使用当前目录目标目录您希望生成的代码在哪里;通常相同$SRC_DIR 以及你的道路.proto。 protoc -I $ SRC_DIR --cpp_out $ DST_DIR $ SRC_DIR / addressbook.proto这里都生成到当前目录输入 protoc -I. --cpp_out. ./addressbook.proto protoc --cpp_out. addressbook.proto // 这种也可以因为您需要C类所以使用该--cpp_out选项 - 为其他支持的语言提供了类似的选项。 这将在指定的目标目录中生成以下文件 addressbook.pb.h标头声明您生成的类。addressbook.pb.cc其中包含您的类的实现。 protobuf_API addressbook.pb.h中可以看到指定的每条消息都有一个类addressbook.proto。对于Person类可以看到编译器已为每个字段生成了访问器。 例如对于名称ID电子邮件和电话字段有以下方法 // name inline bool has_name() const; inline void clear_name(); inline const ::std::string name() const; inline void set_name(const ::std::string value); inline void set_name(const char* value); inline ::std::string* mutable_name();// id inline bool has_id() const; inline void clear_id(); inline int32_t id() const; inline void set_id(int32_t value);// email inline bool has_email() const; inline void clear_email(); inline const ::std::string email() const; inline void set_email(const ::std::string value); inline void set_email(const char* value); inline ::std::string* mutable_email();// phones inline int phones_size() const; inline void clear_phones(); inline const ::google::protobuf::RepeatedPtrField ::tutorial::Person_PhoneNumber phones() const; inline ::google::protobuf::RepeatedPtrField ::tutorial::Person_PhoneNumber * mutable_phones(); inline const ::tutorial::Person_PhoneNumber phones(int index) const; inline ::tutorial::Person_PhoneNumber* mutable_phones(int index); inline ::tutorial::Person_PhoneNumber* add_phones();对于字符串 一个mutable_让你获得指向字符串的直接指针的getter以及一个额外的setter。请注意mutable_email()即使email尚未设置您也可以进行呼叫; 它将自动初始化为空字符串。如果你在这个例子中有一个单数的消息字段它也有一个mutable_方法但不是一个set_方法。 重复的字段也有一些特殊的方法 - 如果你看一下repeated phones字段的方法你会发现你可以 检查重复的字段的_size (换句话说有多少电话号码与此相关联的 Person). 使用索引获取指定的电话号码. 更新指定索引处的现有电话号码. 在邮件中添加另一个电话号码然后可以编辑重复的标量类型add_只允许您传入新值. 有关协议编译器为任何特定字段定义生成的确切成员的详细信息请参阅C 生成的代码参考。 枚举和嵌套类 生成的代码包含PhoneType与您的.proto枚举对应的枚举。您可以参考这个类型Person::PhoneType及其作为值的Person::MOBILEPerson::HOME和Person::WORK实现细节是稍微复杂一点但你并不需要了解他们使用ENUM。 编译器还为您生成了一个嵌套类Person::PhoneNumber。如果查看代码可以看到实际调用了“真实”类Person_PhoneNumber但是在内部定义的typedef Person允许您将其视为嵌套类。唯一不同的情况是如果你想在另一个文件中转发声明类 - 你不能在C中转发声明嵌套类型但你可以转发声明Person_PhoneNumber。 标准消息方法 每个消息类还包含许多其他方法可用于检查或操作整个消息包括 bool IsInitialized() const; 检查是否已设置所有必填字段。 string DebugString() const; 返回消息的人类可读表示对调试特别有用。 void CopyFrom(const Person from); 使用给定消息的值覆盖消息。 void Clear(); 清除所有元素回到空状态。 以下部分中描述的这些和I / O方法实现了Message所有C 协议缓冲区类共享的接口。有关详细信息请参阅完整的API文档Message。 解析和序列化 最后每个协议缓冲区类都有使用协议缓冲区二进制格式编写和读取所选类型消息的方法。这些包括 bool SerializeToString(string output) const;* 序列化消息并将字节存储在给定的字符串中。请注意字节是二进制的而不是文本; 我们只将该 string 类用作方便的容器。 bool ParseFromString(const string data); 解析给定字符串中的消息。 bool SerializeToOstream(ostream output) const;* 将消息写入给定的 C ostream。 bool ParseFromIstream(istream input);* 解析来自给定 C 的消息 istream。 这些只是解析和序列化提供的几个选项。再次请参阅MessageAPI参考以获取完整列表。 写一条消息 现在尝试使用协议缓冲类。地址簿应用程序能够做的第一件事是将个人详细信息写入地址簿文件。为此需要创建并填充协议缓冲区类的实例然后将它们写入输出流。 这是一个程序它从文件中读取一个AddressBook根据用户输入在AddressBook文件中添加一个新的Person然后再将新文本写回文件。直接调用或引用协议编译器生成的代码的部分将突出显示。 #include iostream #include fstream #include string #include addressbook.pb.h using namespace std;// This function fills in a Person message based on user input. void PromptForAddress(tutorial::Person* person) {cout Enter person ID number: ;int id;cin id;person-set_id(id);cin.ignore(256, \n);cout Enter name: ;getline(cin, *person-mutable_name());cout Enter email address (blank for none): ;string email;getline(cin, email);if (!email.empty()) {person-set_email(email);}while (true) {cout Enter a phone number (or leave blank to finish): ;string number;getline(cin, number);if (number.empty()) {break;}tutorial::Person::PhoneNumber* phone_number person-add_phones();phone_number-set_number(number);cout Is this a mobile, home, or work phone? ;string type;getline(cin, type);if (type mobile) {phone_number-set_type(tutorial::Person::MOBILE);} else if (type home) {phone_number-set_type(tutorial::Person::HOME);} else if (type work) {phone_number-set_type(tutorial::Person::WORK);} else {cout Unknown phone type. Using default. endl;}} }// Main function: Reads the entire address book from a file, // adds one person based on user input, then writes it back out to the same // file. int main(int argc, char* argv[]) {// Verify that the version of the library that we linked against is// compatible with the version of the headers we compiled against.GOOGLE_PROTOBUF_VERIFY_VERSION;if (argc ! 2) {cerr Usage: argv[0] ADDRESS_BOOK_FILE endl;return -1;}tutorial::AddressBook address_book;{// Read the existing address book.fstream input(argv[1], ios::in | ios::binary);if (!input) {cout argv[1] : File not found. Creating a new file. endl;} else if (!address_book.ParseFromIstream(input)) {cerr Failed to parse address book. endl;return -1;}}// Add an address.PromptForAddress(address_book.add_people());{// Write the new address book back to disk.fstream output(argv[1], ios::out | ios::trunc | ios::binary);if (!address_book.SerializeToOstream(output)) {cerr Failed to write address book. endl;return -1;}}// Optional: Delete all global objects allocated by libprotobuf.google::protobuf::ShutdownProtobufLibrary();return 0; }注意GOOGLE_PROTOBUF_VERIFY_VERSION宏。在使用C 协议缓冲区库之前执行此宏是一种很好的做法 - 尽管不是绝对必要的。它验证您没有意外链接到与您编译的标头版本不兼容的库版本。如果检测到版本不匹配程序将中止。请注意每个.pb.cc文件在启动时都会自动调用此宏。 还要注意ShutdownProtobufLibrary()程序结束时的调用。所有这一切都是删除协议缓冲区库分配的所有全局对象。对于大多数程序来说这是不必要的因为该过程无论如何都要退出操作系统将负责回收其所有内存。但是如果您使用需要释放每个最后一个对象的内存泄漏检查程序或者您正在编写可以由单个进程多次加载和卸载的库那么您可能希望强制协议缓冲区清除所有内容。 阅读消息 当然如果无法从中获取任何信息那么地址簿就不会有多大用处此示例读取上面示例创建的文件并打印其中的所有信息。 #include iostream #include fstream #include string #include addressbook.pb.h using namespace std;// Iterates though all people in the AddressBook and prints info about them. void ListPeople(const tutorial::AddressBook address_book) {for (int i 0; i address_book.people_size(); i) {const tutorial::Person person address_book.people(i);cout Person ID: person.id() endl;cout Name: person.name() endl;if (person.email() ! ) {cout E-mail address: person.email() endl;}for (int j 0; j person.phones_size(); j) {const tutorial::Person::PhoneNumber phone_number person.phones(j);switch (phone_number.type()) {case tutorial::Person::MOBILE:cout Mobile phone #: ;break;case tutorial::Person::HOME:cout Home phone #: ;break;case tutorial::Person::WORK:cout Work phone #: ;break;}cout phone_number.number() endl;}} }// Main function: Reads the entire address book from a file and prints all // the information inside. int main(int argc, char* argv[]) {// Verify that the version of the library that we linked against is// compatible with the version of the headers we compiled against.GOOGLE_PROTOBUF_VERIFY_VERSION;if (argc ! 2) {cerr Usage: argv[0] ADDRESS_BOOK_FILE endl;return -1;}tutorial::AddressBook address_book;{// Read the existing address book.fstream input(argv[1], ios::in | ios::binary);if (!address_book.ParseFromIstream(input)) {cerr Failed to parse address book. endl;return -1;}}ListPeople(address_book);// Optional: Delete all global objects allocated by libprotobuf.google::protobuf::ShutdownProtobufLibrary();return 0; }编译 g -Wall -stdc11 write.cpp addressbook.pb.cc -o write pkg-config --cflags --libs protobuf g -Wall -stdc11 read.cpp addressbook.pb.cc -o read pkg-config --cflags --libs protobufProtobuf扩展 在释放使用协议缓冲区的代码之后迟早您无疑会想要“改进”协议缓冲区的定义。如果你希望你的新缓冲区向后兼容并且你的旧缓冲区是向前兼容的 - 而且你几乎肯定想要这个 - 那么你需要遵循一些规则。在新版本的协议缓冲区中 不得更改任何现有字段的标记号。 不得添加或删除任何必填字段。 可以删除可选或重复的字段。 可以添加新的可选或重复字段但必须使用新的标记号即从未在此协议缓冲区中使用的标记号甚至不包括已删除的字段。 这些规则有一些例外但它们很少使用。 如果您遵循这些规则旧代码将很乐意阅读新消息并简单地忽略任何新字段。对于旧代码已删除的可选字段将只具有其默认值删除的重复字段将为空。新代码也将透明地读取旧消息。但是请记住旧的消息中不会出现新的可选字段因此您需要明确检查它们是否已设置has_或者在.proto文件中提供合理的默认值[default value]标签号后面。如果未为可选元素指定默认值则使用特定于类型的默认值对于字符串默认值为空字符串。对于布尔值默认值为false。对于数字类型默认值为零。另请注意如果添加了新的重复字段则新代码将无法判断它是否为空通过新代码或从未设置通过旧代码因为没有has_标记。 优化 C 协议缓冲区库经过了极大的优化。但是正确使用可以进一步提高性能。以下是从库中挤出最后一滴速度的一些提示 尽可能重用消息对象。消息尝试保留它们分配用于重用的任何内存即使它们被清除。因此如果您连续处理具有相同类型和类似结构的许多消息则每次重新使用相同的消息对象来加载内存分配器是个好主意。但是随着时间的推移对象会变得臃肿特别是如果您的消息在“形状”上有所不同或者您偶尔构造的消息比平常大得多。 您应该通过调用SpaceUsed方法来监视消息对象的大小并在它们变得太大时删除它们。 您的系统内存分配器可能没有针对从多个线程分配大量小对象进行良好优化。请尝试使用Google的tcmalloc。 高级用法 协议缓冲区的用途不仅仅是简单的访问器和序列化。请务必浏览C API参考以了解您可以使用它们做些什么。 协议消息类提供的一个关键特性是反射。您可以迭代消息的字段并操纵它们的值而无需针对任何特定的消息类型编写代码。使用反射的一种非常有用的方法是将协议消息转换为与其他编码例如XML或JSON之间的转换。更高级的反射使用可能是找到两个相同类型的消息之间的差异或者开发一种“协议消息的正则表达式”您可以在其中编写与某些消息内容匹配的表达式。如果您运用自己的想象力可以将协议缓冲区应用于比您最初预期更广泛的问题 Message::Reflection界面 提供反射。 我的github地址
http://www.zqtcl.cn/news/56630/

相关文章:

  • 18+网站推广网站禁止ping
  • 网站要服务器吗wordpress上传源代码
  • 做网站需要学习哪些经典网站设计欣赏
  • 网站后台有什么用新沂今天重大新闻
  • 免费中文网站模板下载wordpress带下载功能
  • 网站注册qq黔江做网站
  • 网站建设万户平面设计接单能赚多少钱
  • 网站建设与管理学的是什么公司网站开发外包公司
  • dw做网站时怎么改为绝对路径网站平台 生态建设
  • 长春网站快照优化公司django做网站快吗
  • wordpress远程访问成都高新seo
  • 怎么做视频资源网站安全等级保护每个网站必须做吗
  • php网站开发周期多长玉溪网站建设公司哪家好
  • 网站建设中如何设置外链接wordpress 博客 页面
  • 扁平风网站竞价推广岗位职责
  • 低代码建站平台建立一个做笔记的网站
  • 建设网站有哪些参考文献佛山企业制作网站
  • 网站设置cookie什么意思凡科网站手机投票怎么做
  • 如何做服装的微商城网站建设广州有几个区哪个区最好
  • 做学校网站素材图片大全泰兴网站设计
  • 网站中如何做图片轮播网站开发常用的框架
  • 做优化网站能以量取胜么wordpress 悬浮插件
  • 儿童摄影网站怎么做济南哪个公司做网站好
  • 网站建设与管理实训心得宣传片拍摄应急预案
  • 建设网站破解版网站 备案网站
  • 黄山网站设计wordpress获取路径
  • 河北做网站公司那家好做网站常用字体
  • 建设电商网站流程网站建设备案审核要多久
  • 网站建设有前途吗黄梅那里有做网站的
  • 山东聊城做网站wordpress在线阅读主题