Compiling proto and related usage of proto
1. Compiling proto
Reinstall the protoc ol for reference https://blog.csdn.net/u013498583/article/details/74231058
View the current protocol version: protocol -- version
Check the installation location of protocol: which protoc ol
Find the file related to the protocol: sudo find / - name protocol
Compiling proto files
protoc caffe.proto --cpp_out=./ Generate cafe pb. h,caffe.pb.cc file
protoc caffe.proto --python_out=./ Generate caffe_pb2.py file
If more than one protocol version is installed in the environment, you can double-click the tab key with protocol to pop up all versions (protocol protocol_2.6.1, where protocol is the default version and protocol -- version is to view the current default protocol version).
If we want to compile proto using a non default version of protoc, we can use protoc_2.6.1 caffe.proto --cpp_out=./ Compile this way.
When compiling mobilenet Yolo project, use protocol_ 2.6.1 compiled cafe pb. h ,caffe. pb. Paste the CC file into caffe\include\caffe\proto.
2. Usage of proto
For example, there is proto_name.proto file, put this proto_ name. After the proto file is compiled, proto will be generated_ name. pb. h and proto_name.pb.cc, generated The classes in h file are inherited from:: google::protobuf::Message class. Message class provides some methods to check or operate the whole message, including:
bool IsInitialized() const; // Check whether all required variables have been initialized; string DebugString() const; // Return the readable representation of message, which is mainly used for debugging programs; void CopyFrom(const Person& from); // Overwrite this message with the value of a message; void Clear(); // Clear all member variable values of message.
Each message class provides methods to write and read message data, including
bool SerializeToString(string* output) const; // Encode message into output. bool ParseFromString(const string& data); // Decode from string to message bool SerializeToArray(char* buf,int size) const; // Encode message into the array buf bool ParseFromArray(const char* buf,int size); // Decode buf to message. This decoding method is much more efficient than ParseFromString, so it is generally used for decoding. bool SerializeToOstream(ostream* output) const; // Encode message into ostream bool ParseFromIstream(istream* input); // Decoding from istream to message Note: the encoding and decoding method used by the sender and receiver does not have to be paired, that is, the sender uses it SerializeToString The receiving end does not have to be used ParseFromString ,Other decoding methods can be used.
Generally, bool SerializeToString(string* output) const is used; And bool SerializeToArray(char* buf,int size) const;
For example, when you need to use tcp/udp to send a containing array, it is recommended to use bool SerializeToArray(char* buf,int size) const;, Because of the need to use array index when it comes to packet headers and check bits, it is best to use SerializeToArray.
#define _fill_pack(name) \ { \ char tbuf[256 * 1024]; \ uint32_t len = name.ByteSize(); \ auto header = name.header(); \ _fill_pack_head(static_cast<uint32_t>(netproxy_##name##_pack), len, \ reinterpret_cast<netproxy_pack_t *>(tbuf)); \ if (!name.SerializeToArray(&tbuf[sizeof(netproxy_pack_t)], len)) { \ SERROR << "serialize error, name:" << #name << " len:" << len; \ len = -sizeof(netproxy_pack_t); \ } \ Send_data(tbuf, len + sizeof(netproxy_pack_t), netproxy_##name##_pack); \ }
At other times, you can directly use SerializeToString.
Usage 1: compatibility of message structure of external interface
When the structure of a variable in the message structure msgA of an external interface always needs to be frequently added, deleted and modified according to requirements, an STD:: String proto is generally defined in the message structure msgA_ Data variables,
In this way, you only need to modify the proto_ name. The contents in the proto file do not always need to modify msgA (especially when modifying msgA may need to modify the framework protocol, in short, it is relatively expensive). It is particularly convenient to use the proto method to solve this problem.
Original structure:
struct msgA{### 1. Compiling proto Reload protoc Can refer to https://blog.csdn.net/u013498583/article/details/74231058 View current protoc edition: `protoc --version` see protoc Installation position:`which protoc` lookup protoc Relevant documents:`sudo find / -name protoc` compile proto file `protoc caffe.proto --cpp_out=./ generate caffe.pb.h,caffe.pb.cc file` `protoc caffe.proto --python_out=./ generate caffe_pb2.py file` If more than one is installed in the environment protoc Version, available protoc double-click tab Key, all versions will pop up(`protoc protoc_2.6.1`,among`protoc`Is the default version,`protoc --version`The default is current view protoc Version). If we want to use a non default version protoc compile proto,sure`protoc_2.6.1 caffe.proto --cpp_out=./`Compile this way. Compiling MobileNet-YOLO When working, use protoc protoc_2.6.1 Compiled `caffe.pb.h` ,`caffe.pb.cc` Paste file into `caffe\include\caffe\proto`Just. ### 2. Usage of proto For example, yes `proto_name.proto`File, put this `proto_name.proto`After the file is compiled, a `proto_name.pb.h` and `proto_name.pb.cc`, Generated.h In the file class All inherited from`::google::protobuf::Message`Class,`Message`Class provides methods to check or manipulate the entire message,include: ```c++ bool IsInitialized() const; // Check whether all required variables have been initialized; string DebugString() const; // Return the readable representation of message, which is mainly used for debugging programs; void CopyFrom(const Person& from); // Overwrite this message with the value of a message; void Clear(); // Clear all member variable values of message.
Each message class provides methods to write and read message data, including
bool SerializeToString(string* output) const; // Encode message into output. bool ParseFromString(const string& data); // Decode from string to message bool SerializeToArray(char* buf,int size) const; // Encode message into the array buf bool ParseFromArray(const char* buf,int size); // Decode buf to message. This decoding method is much more efficient than ParseFromString, so it is generally used for decoding. bool SerializeToOstream(ostream* output) const; // Encode message into ostream bool ParseFromIstream(istream* input); // Decoding from istream to message Note: the encoding and decoding method used by the sender and receiver does not have to be paired, that is, the sender uses it SerializeToString The receiving end does not have to be used ParseFromString ,Other decoding methods can be used.
Generally, bool SerializeToString(string* output) const is used; And bool SerializeToArray(char* buf,int size) const;
For example, when you need to use tcp/udp to send a containing array, it is recommended to use bool SerializeToArray(char* buf,int size) const;, Because of the need to use array index when it comes to packet headers and check bits, it is best to use SerializeToArray.
#define _fill_pack(name) \ { \ char tbuf[256 * 1024]; \ uint32_t len = name.ByteSize(); \ auto header = name.header(); \ _fill_pack_head(static_cast<uint32_t>(netproxy_##name##_pack), len, \ reinterpret_cast<netproxy_pack_t *>(tbuf)); \ if (!name.SerializeToArray(&tbuf[sizeof(netproxy_pack_t)], len)) { \ SERROR << "serialize error, name:" << #name << " len:" << len; \ len = -sizeof(netproxy_pack_t); \ } \ Send_data(tbuf, len + sizeof(netproxy_pack_t), netproxy_##name##_pack); \ }
At other times, you can directly use SerializeToString.
Usage 1: compatibility of message structure of external interface
When the structure of a variable in the message structure msgA of an external interface always needs to be frequently added, deleted and modified according to requirements, an STD:: String proto is generally defined in the message structure msgA_ Data variables,
In this way, you only need to modify the proto_ name. The contents in the proto file do not always need to modify msgA (especially when modifying msgA may need to modify the framework protocol, in short, it is relatively expensive). It is particularly convenient to use the proto method to solve this problem.
Original structure:
struct msgA{ MsgHeader header; bool is_ok; structBBB msgbbb; //When it is troublesome to add, delete and modify the structure of structBBB, it will cause the trouble of frequently modifying the external interface msgA. }
method:
Define a proto first_ name. Proto file, put this proto_ name. After the proto file is compiled, proto will be generated_ name. pb. H and proto_name.pb.cc,
The assignment to the variable defined in it is to use set_xxx(111) function is used to assign values. After the assignment is completed, it is serialized and then packaged and sent;
Use proto before sending_ name. Serializetostring (& data) serializes the structure into string type and then sends it.
The original structure is modified to:
struct msgA{ MsgHeader header; bool is_ok; //Define a string type structure to replace structBBB msgbbb; Then the data structure defined by proto is proto_ name. After proto assignment, //Call proto_name.SerializeToString(proto_data) is serialized, converted into string and assigned to proto_ Data variable, which is solved by using proto. std::string proto_data; }
In the following functions, we encapsulate the SerializeToString and ParseFromString methods of proto
// msg to string template <class T> void MsgToString(const T msg, std::string &data) { msg.SerializeToString(&data); } // Convert string to msg template <class T> void StringToMsg(const std::string data, T &msg) { msg.ParseFromString(data); }
Usage 2:
When we need to use the configuration file to assign values to many variables, we can define all these variables in config Proto, and then create a config pb. Txt file, in config pb. Txt file Set the variables in proto.
Read config. Later pb. Txt file, and then get these contents where needed.
The code involves file reading, parsing, proto and so on. It is a little complex. We won't expand it for the time being. Here we just point out that it has this usage.
MsgHeader header;
bool is_ok;
structBBB msgbbb; // When it is troublesome to add, delete and modify the structure of structbbb, it will cause the trouble of frequently modifying the external interface msgA.
}
##### method: First define a proto_name.proto File, put this proto_name.proto After the file is compiled, a proto_name.pb.h and proto_name.pb.cc, Assigning values to variables defined therein is done using set_xxx(111) Function, and then serialize it after the assignment is completed, and then package and send it; Use before sending proto_name.SerializeToString(&data) Serialize the structure into string Type before sending. The original structure is modified to: ```c++ struct msgA{ MsgHeader header; bool is_ok; //Define a string type structure to replace structBBB msgbbb; Then the data structure defined by proto is proto_ name. After proto assignment, //Call proto_name.SerializeToString(proto_data) is serialized, converted into string and assigned to proto_ Data variable, which is solved by using proto. std::string proto_data; }
In the following functions, we encapsulate the SerializeToString and ParseFromString methods of proto
// msg to string template <class T> void MsgToString(const T msg, std::string &data) { msg.SerializeToString(&data); } // Convert string to msg template <class T> void StringToMsg(const std::string data, T &msg) { msg.ParseFromString(data); }
Usage 2:
When we need to use the configuration file to assign values to many variables, we can define all these variables in config Proto, and then create a config pb. Txt file, in config pb. Txt file Set the variables in proto.
Read config. Later pb. Txt file, and then get these contents where needed.
The code involves file reading, parsing, proto and so on. It is a little complex. We won't expand it for the time being. Here we just point out that it has this usage.