C++ google protobuf

前言

本篇介紹的是TensorRT中用到的幾個與google/protobuf有關的函數。

google::protobuf

google::protobuf::io::ZeroCopyInputStream

摘自class ZeroCopyInputStream

其所屬header檔及命名空間為:

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

其角色為:

Abstract interface similar to an input stream but 
designed to minimize copying.

一個被設計用來減少複製的input stream,為一抽象的interface。

google::protobuf::io::IstreamInputStream

摘自class IstreamInputStream

其所屬header檔及命名空間為:

#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace google::protobuf::io

其角色為:

A ZeroCopyInputStream which reads from a C++ istream.

IstreamInputStreamZeroCopyInputStream的子類別,其功能是從C++的istream中讀取數據。

參考IstreamInputStream constructor,其建構子的簽名為:

explicit IstreamInputStream::IstreamInputStream(
        std::istream * stream,
        int block_size = -1)

作用為:

Creates a stream that reads from the given C++ istream.
If a block_size is given, it specifies the number of bytes that 
should be read and returned with each call to Next(). 
Otherwise, a reasonable default is used.

即創建一個從C++ istream裡讀取數據的流。它會讀取block_size個bytes。

google::protobuf::io::CodedInputStream

摘自class CodedInputStream

其所屬header檔及命名空間為:

#include <google/protobuf/io/coded_stream.h>
namespace google::protobuf::io

其角色為:

Class which reads and decodes binary data which is composed of 
varint-encoded integers and fixed-width pieces.

CodedInputStream用於讀取binary data並對其解碼。

其建構子簽名為:

explicit CodedInputStream(ZeroCopyInputStream * input)

作用為:

Create a CodedInputStream that reads 
from the given ZeroCopyInputStream.

可以把CodedInputStream想成是ZeroCopyInputStream的wrapper,用於從ZeroCopyInputStream讀取數據並解碼。

google::protobuf::io::CodedInputStream codedModelStream(&modelStream);## google::protobuf::TextFormat::Parse

SetTotalBytesLimit

參考CodedInputStream::SetTotalBytesLimit,其函數簽名為:

void CodedInputStream::SetTotalBytesLimit(
    int total_bytes_limit)

其作用為:

Sets the maximum number of bytes that this CodedInputStream 
will read before refusing to continue.

即設定CodedInputStream物件將讀取的最大bytes數。

根據coded_stream.h

PROTOBUF_DEPRECATED_MSG("Please use the single parameter version 
of SetTotalBytesLimit(). The " "second parameter is ignored." )

在這個版本中如果給它傳第二個參數將被忽略。

google::protobuf::io::ArrayInputStream

摘自class ArrayInputStream

其所屬header檔及命名空間為:

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google::protobuf::io

其角色為:

A ZeroCopyInputStream backed by an in-memory array of bytes.

ArrayInputStreamZeroCopyInputStream的子類別,用於從記憶體裡的陣列中逐byte地讀取數據。

參考ArrayInputStream - constructor,其建構子簽名為:

ArrayInputStream::ArrayInputStream(
        const void * data,
        int size,
        int block_size = -1)

作用為:

Create an InputStream that returns the bytes pointed to by "data".

即創建一個指向data這個bytes陣列的InputStream

google::protobuf::ShutdownProtobufLibrary

摘自common.h,其所屬header檔及命名空間為:

#include <google/protobuf/stubs/common.h>
namespace google::protobuf

摘自protobuf::ShutdownProtobufLibrary

Shut down the entire protocol buffers library, 
deleting all static-duration objects allocated by 
the library or by generated .pb.cc files.

其作用為關閉protobuf library本身。

google::protobuf::TextFormat::Parse

參考google::protobuf::TextFormat::Parse

其所屬header檔及命名空間為:

#include <google/protobuf/text_format.h>
namespace google::protobuf

其函數簽名為:

static bool TextFormat::Parse(
        io::ZeroCopyInputStream * input,
        Message * output)

作用為:

Parses a text-format protocol message from the 
given input stream to the given message object.

即從給定的ZeroCopyInputStream裡讀取並解析文字格式的protocol message,存到給定的Message物件當中。如果成功則回傳true,否則回傳false。

google::protobuf::RepeatedField::Get

repeated_field.h - template class RepeatedField

google::protobuf::RepeatedField所屬header檔、命名空間及template為:

#include <google/protobuf/repeated_field.h>
namespace google::protobuf

template <typename Element>

其角色為:

RepeatedField is used to represent repeated fields of a primitive type (in other words, everything except strings and nested Messages).

Most users will not ever use a RepeatedField directly; they will use the get-by-index, set-by-index, and add accessors that are generated for all repeated fields.

它是用於表示.proto檔中的repeated field。

google::protobuf::RepeatedField::Get函數的簽名為:

const Element &	Get(int index) const

它的作用是獲取repeated field的第index個元素。

MessageLite::ParseFromCodedStream

參考MessageLite::ParseFromCodedStream

其所屬header檔及命名空間為:

#include <google/protobuf/message_lite.h>
namespace google::protobuf

它屬於MessageLite類別的成員函數,其函數簽名為:

bool MessageLite::ParseFromCodedStream(
    io::CodedInputStream * input)

其作用為:

Fill the message with a protocol buffer parsed 
from the given input stream.

即從給定的input stream裡解析出protocol buffer,並填入message物件中。

參考Protocol Buffer(proto2)及C++ API,此處的MessageLite有一個名為Message的子類別。而我們知道.proto裡的一個message會對應到.proto.pb.h裡定義的一個類別,而.proto.pb.h裡定義的每個類別都會實作Message這個interface。所以每個從.proto裡來的類別都可以直接調用ParseFromCodedStream這個函數。

TensorRT中的例子

TensorRT/parsers/caffe/caffeParser/readProto.h 的函數 readBinaryProto中:

bool readBinaryProto(trtcaffe::NetParameter* net, const char* file, size_t bufSize)
{
    //...
    using namespace google::protobuf::io;

    std::ifstream stream(file, std::ios::in | std::ios::binary);
    //...
    //創建一個從C++ istream裡讀取數據的流
    IstreamInputStream rawInput(&stream);
    /*
    IstreamInputStream為ZeroCopyInputStream的子類別
    從ZeroCopyInputStream讀取數據並解碼。
    */
    CodedInputStream codedInput(&rawInput);
    //設定CodedInputStream物件將讀取的最大bytes數,第二個參數將被忽略
    codedInput.SetTotalBytesLimit(int(bufSize), -1);
    /*
    從給定的input stream裡解析出protocol buffer,
    並填入net這個message物件中
    */
    bool ok = net->ParseFromCodedStream(&codedInput);
    //...
}

函數readTextProto

bool readTextProto(trtcaffe::NetParameter* net, const char* file)
{
    //...
    using namespace google::protobuf::io;

    std::ifstream stream(file, std::ios::in);
    //...
    IstreamInputStream input(&stream);
    /*
    從給定的ZeroCopyInputStream裡讀取並解析文字格式的protocol message,
    存到給定的Message物件net當中
    */
    bool ok = google::protobuf::TextFormat::Parse(&input, net);
    //...
}

TensorRT/parsers/caffe/caffeParser/caffeParser.cpp的函數parse中:

dims = DimsCHW{(int) mDeploy->input_shape().Get(i).dim().Get(1), (int) mDeploy->input_shape().Get(i).dim().Get(2), (int) mDeploy->input_shape().Get(i).dim().Get(3)};

其中mDeploy->input_shape()是一個repeated field:

message NetParameter {
  //...
  repeated BlobShape input_shape = 8;
  //...
}

所以mDeploy->input_shape().Get(i)代表獲取input_shape的第i個元素。

我們可以從BlobShape的定義:

message BlobShape {
  repeated int64 dim = 1 [packed = true];
}

中看到,dim也是一個repeated field。

所以xxx.dim().Get(yyy)代表獲取dim的第yyy個元素。

參考連結

class ZeroCopyInputStream

class IstreamInputStream

IstreamInputStream constructor

class CodedInputStream

CodedInputStream::SetTotalBytesLimit

coded_stream.h

class ArrayInputStream

ArrayInputStream - constructor

common.h

protobuf::ShutdownProtobufLibrary

google::protobuf::TextFormat::Parse

MessageLite::ParseFromCodedStream

Protocol Buffer(proto2)及C++ API

repeated_field.h - template class RepeatedField

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值