欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Protobuf 動態(tài)加載 .proto 文件并操作 Message

Google Protocol Buffer 的常規(guī)用法需要使用 protoc.proto 編譯成 .pb.h.pb.cc,這樣做效率非常高,但是耦合性也很高。在某些追求通用性而不追求性能的場景下,需要使用 .proto 直接操作 protobuf 數(shù)據(jù)。

創(chuàng)新互聯(lián)公司-成都網(wǎng)站建設(shè)公司,專注網(wǎng)站設(shè)計、網(wǎng)站制作、網(wǎng)站營銷推廣,域名注冊,網(wǎng)頁空間,網(wǎng)站托管運營有關(guān)企業(yè)網(wǎng)站制作方案、改版、費用等問題,請聯(lián)系創(chuàng)新互聯(lián)公司。

本例使用的 .proto 文件來自 https://developers.google.com/protocol-buffers/docs/cpptutorial ,但是把它拆成了兩個 .proto 文件

// ./proto/person.proto
syntax = "proto2";
package tutorial;

message Person {
  optional string name = 1;
  optional int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    optional string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phones = 4;
}
// ./proto/adressbook.proto
syntax = "proto2";
package tutorial;
import "person.proto";

message AddressBook {
  repeated Person people = 1;
}

示例代碼

#include <iostream>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/util/json_util.h>

using namespace google::protobuf;

/*
構(gòu)造 Importer 必須指定 error_collector 用于處理錯誤信息
AddError 是純虛函數(shù),必須 override
*/
class MyMultiFileErrorCollector : public compiler::MultiFileErrorCollector
{
      virtual void AddError(const std::string& filename, int line, int column, const std::string& message) override
      {
          std::cout << "file: " << filename << ", line: " << line << ", col: " << column<< ", message: " << message << std::endl; 
      }
};

int main()
{
    /*
    構(gòu)造 DiskSourceTree,并添加虛擬路徑。protobuf 使用 Importor 導入 .proto 文件時,會使用虛擬路徑進行查找
    在本例中,導入 addressbook.proto 時會使用 ./proto/addressbook.proto
    */
    compiler::DiskSourceTree disk_source_tree;
    disk_source_tree.MapPath("", "proto");

    MyMultiFileErrorCollector error_collector;

    /*
    導入 addressbook.proto 時,會自動導入所有依賴的 .proto 文件
    在本例中,person.proto 也會被自動導入
    */
    compiler::Importer importer(&disk_source_tree, &error_collector);
    const FileDescriptor* file_descriptor = importer.Import("addressbook.proto");
    if (!file_descriptor) {
        exit(-1);
    }

    // 把 addressbook.proto 和 person.proto 都打印出來
    std::cout << "====== all .proto files ======" << std::endl;
    std::cout << file_descriptor->DebugString() << std::endl;
    for (int i = 0; i < file_descriptor->dependency_count(); ++i) {
        std::cout << file_descriptor->dependency(i)->DebugString() << std::endl;
    }
    
    /*
    查找 Person 的 Descriptor 
    不能使用 file_descriptor 查找,它只包含 addresssbook.proto ,只能找到 AddressBook,而 DescriptorPool 包含了所有數(shù)據(jù)
    在使用 DescriptorPool 查找時需要使用全名,如:tutorial.Person
    在使用 FileDescritor 查找時需要使用頂級名字,如:AddressBook,而不是 tutorial.AddressBook
    */
    const Descriptor* person_descriptor = importer.pool()->FindMessageTypeByName("tutorial.Person");
    
    /*
    使用工廠創(chuàng)建默認 Message,然后構(gòu)造一個可以用來修改的 Message
    這個 Message 的生命周期由 New 調(diào)用者管理
    */
    DynamicMessageFactory message_factory;
    const Message* default_person = message_factory.GetPrototype(person_descriptor);
    Message* person = default_person->New();

    // 使用 Reflection 修改 Message 的數(shù)據(jù)
    const Reflection* reflection = person->GetReflection();
    reflection->SetString(person, person_descriptor->FindFieldByName("name"), "abc");
    reflection->SetInt32(person, person_descriptor->FindFieldByName("id"), );
    reflection->SetString(person, person_descriptor->FindFieldByName("email"), "abc@163.com");

    // 把動態(tài)設(shè)置的 Message 的數(shù)據(jù)以 JSON 格式輸出
    util::JsonPrintOptions json_options;
    json_options.add_whitespace = true;
    json_options.always_print_primitive_fields = true;
    json_options.preserve_proto_field_names = true;
    std::string output;
    util::MessageToJsonString(*person, &output, json_options);
    std::cout << "====== Person data ======" << std::endl;
    std::cout << output;

    // 析構(gòu) person
    delete person;
}

輸出

====== all .proto files ======
syntax = "proto2";

import "person.proto";
package tutorial;

message AddressBook {
  repeated .tutorial.Person people = 1;
}


syntax = "proto2";

package tutorial;

message Person {
  message PhoneNumber {
    optional string number = 1;
    optional .tutorial.Person.PhoneType type = 2 [default = HOME];
  }
  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }
  optional string name = 1;
  optional int32 id = 2;
  optional string email = 3;
  repeated .tutorial.Person.PhoneNumber phones = 4;
}


====== Person data ======
{
 "name": "abc",
 "id": ,
 "email": "abc@163.com",
 "phones": []
}

https://developers.google.com/protocol-buffers/docs/reference/cpp

名稱欄目:Protobuf 動態(tài)加載 .proto 文件并操作 Message
網(wǎng)站鏈接:http://chinadenli.net/article26/dsogojg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、微信公眾號域名注冊、微信小程序網(wǎng)站收錄、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司