Google.Protobuf

一、环境搭建

1、下载软件

https://github.com/protocolbuffers/protobuf/releases

2、为.exe文件设置环境变量

 电脑 - 属性 - 高级系统设置 - 高级 - 环境变量 - 编辑用户变变量的Path变量-添加protoc.exe的所在目录

3、迁移include文件夹下的文件

将include/google文件夹移动到指定了环境变量的文件夹

 

 

 

二、编写.proto文件

syntax 来指明 使用版本
syntax = "proto2";  或 syntax = "proto3";  

package 对应于c#中的命名空间

创建命名空间(package)
示例:package Micro.IMSSDK;
结果:namespace Micro.IMSSDK { ... }


required 对应类的属性 (该变量必填)
optional 创建一个具有默认值的属性,通过[default=XXX]设置默认值,不添加默认为空置。如string默认为“”,int默认为0
enum 创建枚举
message 创建自定义类或内部类
repeated 对应list列表数据
import 导入引用
参考文档:
Protobuf 语法简明教程
https://blog.csdn.net/crazymakercircle/article/details/83904366
https://www.cnblogs.com/crazymakercircle/p/9937026.html
https://blog.csdn.net/sylar_d/article/details/51325987

三、生成代码

1、进入目录,输入cmd
2、复制google文件夹至目录
3、复制.proto文件至目录
4、生成csharp文件,如:protoc --csharp_out=./ chat.proto

 

proto2与proto3的基本语法

1)注释 //
 
2)选择哪个版本协议
syntax = "proto2"
或
syntax = "proto3"
 
3)定义一个协议类型,先从2讲起
syntax = "proto2"
message my_person { // 消息开始
	required string name = 1;
	required int32 age = 2;
	optional int32 sex = 3;
	repeated uint32 array_value = 4;
} // 消息结束
 
4)每一行
// 字段规则(required) 字段类型(int32) 字段名字(age) 字段标识号(1)
 
5)规则
required: 该值必须设置
optional: 可以不设置,不设置则不会编码进去; 解码后是默认值
repeated: 字段可以重复任意多次(包括0次),类似于List、vector数组
 
6)数据类型
double
float
int32
sint32: 编码为负数时,比int32高效
int 64
sint64
fixed32:
fixed64:
sfixed32:
sfixed64:
bool: utf-8 或 7-bit ascii
string:
bytes:
 
7)每次定义完一个数据成员,以分号结尾
 
8)枚举
enum Direction {
	START = 0;
	EAST = 1;
	SOUTH = 2;
	WEST = 3;
	NORTH = 4;
};
 
9)包: 防止不同消息类型,存在命名冲突。 c/c++是名字空间
package test;
 
10)message的嵌套使用
message address_book {
	repeated myperson persons = 1; // 人物联系表
}
 
11)proto3与proto2的区别
  (1)移除required
      λ protoc.exe --cpp_out=./ test3.proto
	  test3.proto:16:18: Explicit 'optional' labels are disallowed in the Proto3 syntax. To define 'optional' fields in Proto3, simply remove the 'optional' label, as fields are 'optional' by default.
  (2)optional改为singular(也去掉)
  (3)移除了default选项。proto3中,字段的默认值只能根据字段类型由系统决定
  (4)枚举类型的第一个字段必须为0
      λ protoc.exe --cpp_out=./ test3.proto
	  test3.proto: The first enum value must be zero in proto3.
 
12)proto2
syntax = "proto2";
package test;
 
enum Direction {
	START = 0;
	EAST = 1;
	SOUTH = 2;
	WEST = 3;
	NORTH = 4;
};
 
message myperson { // 消息开始
	required string name = 1;
	required int32 age = 2;
	optional int32 sex = 3;
	repeated uint32 array_value = 4;
} // 消息结束
 
message address_book {
	repeated myperson persons = 1; // 人物联系表
}
 
13)proto3
syntax = "proto3";
package test;
enum Direction {
	EAST = 1;
	SOUTH = 2;
	WEST = 3;
	NORTH = 4;
};
 
message myperson { // 消息开始
	string name = 1;
	int32 age = 2;
	int32 sex = 3;
	repeated uint32 array_value = 4;
} // 消息结束
 
message address_book {
	repeated myperson persons = 1; // 人物联系表
}

C# 使用protobuf序列化反序列化数据

参考:https://www.cnblogs.com/luludongxu/p/17952865  

https://www.cnblogs.com/Dotnet9-com/p/12052131.html

C# 中使用 Protocol Buffers 協定來序列化與反序列化物件

https://blog.yowko.com/csharp-protobuf-serialize-deserialize/

protobuf反序列化数据

var buffer = new byte[1024 * 4];
var result = new ArraySegment<byte>(buffer);
var myMessage = MyMessage.Parser.ParseFrom(buffer.AsSpan(0, result.Count).ToArray());

 或者

MyMessage t = new MyMessage();
byte[] data = new byte[t.CalculateSize()];
using (CodedOutputStream cos = new CodedOutputStream(data))
{
    t.WriteTo(cos);
    //data = cos.to.ToArray();
}

 

反序列化

MyMessaget = MyMessage.Parser.ParseFrom(data);

 

posted @ 2021-07-15 18:20  microsoft-zhcn  阅读(376)  评论(0编辑  收藏  举报