1. protobuf安装
下载https://github.com/google/protobuf/releases ##Source code (zip)##
./autogen.sh
./configure
make
make check
make install
当安装有anaconda时,系统会默认调用anaconda中的protoc,所以需要手动将anaconda中的protoc替换为编译的版本
which protoc // 查看protoc安装位置
whereis protoc // 查看所有protoc安装位置
protoc--version //查看protoc版本
2. protoc使用
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 phone = 4;
}
生成对应的c++文件
protoc --cpp_out=./ ./Person.proto
代码
#include <iostream>
#include <fstream>
#include <fcntl.h>
#include <zconf.h>
#include <tiff.h>
#include "Person.pb.cc"
using namespace std;
void write_person() {
tutorial::Person sr;
sr.set_name("mike");
sr.set_email("dsa@sda.com");
sr.set_id(32);
tutorial::Person_PhoneNumber *person_phoneNumber = sr.add_phone();
person_phoneNumber->set_number("1111");
person_phoneNumber->set_type(tutorial::Person::MOBILE);
int fd = open("./pb.xxx", O_CREAT | O_TRUNC | O_RDWR, 0644);
sr.SerializeToFileDescriptor(fd);
close(fd);
}
void read_person() {
int fd = open("./pb.xxx", O_RDONLY);
tutorial::Person person;
if (person.ParseFromFileDescriptor(fd)) {
cout << "name:" << person.name() << endl;
cout << "email:" << person.email() << endl;
cout << "id:" << person.id() << endl;
cout << "phone:" << person.phone(0).number() << endl;
}
}
int main(int argc, char *argv[]) {
write_person();
read_person();
return 0;
}
3. 语法
指定字段规则
所指定的消息字段修饰符必须是如下之一:
singular:一个格式良好的消息应该有0个或者1个这种字段(但是不能超过1个)。
repeated:在一个格式良好的消息中,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。
标量数值类型
一个标量消息字段可以含有一个如下的类型——该表格展示了定义于.proto文件中的类型,以及与之对应的、在自动生成的访问类中定义的类型:
.proto Type Notes C++ Type Java Type Python Type[2] Go Type Ruby Type C# Type PHP Type
double double double float float64 Float double float
float float float float float32 Float float float
int32 使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint64替代 int32 int int int32 Fixnum 或者 Bignum(根据需要) int integer
uint32 使用变长编码 uint32 int int/long uint32 Fixnum 或者 Bignum(根据需要) uint integer
uint64 使用变长编码 uint64 long int/long uint64 Bignum ulong integer/string
sint32 使用变长编码,这些编码在负值时比int32高效的多 int32 int int int32 Fixnum 或者 Bignum(根据需要) int integer
sint64 使用变长编码,有符号的整型值。编码时比通常的int64高效。 int64 long int/long int64 Bignum long integer/string
fixed32 总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效。 uint32 int int uint32 Fixnum 或者 Bignum(根据需要) uint integer
fixed64 总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。 uint64 long int/long uint64 Bignum ulong integer/string
sfixed32 总是4个字节 int32 int int int32 Fixnum 或者 Bignum(根据需要) int integer
sfixed64 总是8个字节 int64 long int/long int64 Bignum long integer/string
bool bool boolean bool bool TrueClass/FalseClass bool boolean
string 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。 string String str/unicode string String (UTF-8) string string
bytes 可能包含任意顺序的字节数据。 string ByteString str []byte String (ASCII-8BIT) ByteString string
参考Protocol Buffer 编码
在java中,无符号32位和64位整型被表示成他们的整型对应形似,最高位被储存在标志位中。
对于所有的情况,设定值会执行类型检查以确保此值是有效。
64位或者无符号32位整型在解码时被表示成为ilong,但是在设置时可以使用int型值设定,在所有的情况下,值必须符合其设置其类型的要求。
python中string被表示成在解码时表示成unicode。但是一个ASCIIstring可以被表示成str类型。
Integer在64位的机器上使用,string在32位机器上使用
枚举
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
}
Corpus corpus = 4;
}
如你所见,Corpus枚举的第一个常量映射为0:每个枚举类型必须将其第一个类型映射为0,这是因为:
必须有有一个0值,我们可以用这个0值作为默认值。
这个零值必须为第一个元素,为了兼容proto2语义,枚举类的第一个值总是默认值。
---------------------
作者:koibiki
来源:CSDN
原文:https://blog.csdn.net/koibiki/article/details/80951962
版权声明:本文为博主原创文章,转载请附上博文链接!
|
|