protobuf、protobuf-net系列库的源码编译以及使用方法

概述

本文内容包括:github上获取源码,用cmake生成工程并编译,简要介绍两种库分别在C++和C#工程中的使用方法。

protobuf

protobuf源码获取

protobuf源码的github地址:
https://github.com/google/protobuf.git
releases中可以获取各版本压缩包。
下文采用git clone获取到3.7.x分支
克隆下来的仓库中包含两个子模块benchmark和googletest,位于third_party中,使用cmake编译进入到third_party目录,执行:
git submodule update --init --recursive

zlib获取和编译

用cmake编译protobuf源码时可能会报错:cmake Could NOT find ZLIB (missing: ZLIB_LIBRARY),我们提前准备好zlib。
下载:zlib-1.2.11.zip
github地址:https://github.com/madler/zlib/releases
进入目录/contrib/vstudio,找到对应版本的vs打开,例如进入vc10,用VS2010打开zlibvc.sln,然后编译zlibvc


编译生成32位Debug(位于x86\ZlibDllDebug\zlibwapid.lib)、32位Release(位于x86\ZlibDllRelease\zlibwapid.lib)、64位Debug(位于x64\ZlibDllDebug\zlibwapi.lib)和64位Release(位于x64\ZlibDllRelease\zlibwapi.lib)

使用cmake生成VS工程

安装cmake 64位,官方网站:https://cmake.org/download/ 下载:cmake-3.9.0-rc3-win64-x64.msi
打开cmake可视化界面,指定protobuf源码的cmake目录和protobuf工程生成目录,勾选Advanced


点击Configure,选择生成VS工程的版本,如下图

选择Visual Studio 15 2017即编译VS2017 win32工程,选择Visual Studio 15 2017 Win64即编译VS2017 win64工程。
若提示无法找到ZLIB,则在窗口中找到下图这三个变量名,设置值

ZLIB_INCLUDE_DIR即zlib源码路径
ZLIB_LIBRARY_DEBUG和ZLIB_LIBRARY_RELEASE分别对应上文编译好的库文件zlibwapid.lib和zlibwapi.lib(注意,若要生成VS win64工程要选择64位的库文件,VS win32工程则选择32位的库文件)
配置好以后,再次点击Configure,如下图:

下方输出栏打印“Configuring done”表示Configure成功,点击Generate,输出栏打印“Generating done”,此时在生成目录可以找到VS工程。

用VS工程编译protubuf

打开VS工程,选择Release Win32或Release Win64进行编译,在输出目录下生成下图protoc.exe及库文件。


受zlib某些因素影响,tests项目可能编译失败,无法生成tests.exe,但没有关系,对库的使用不构成影响

protobuf的使用示例

在protoc.exe所在目录创建一个文件夹作为生成文件夹,例如Generate,并创建一个dataClass.proto文件,写入以下内容:

syntax = "proto2";
message DataPackage{
    repeated double real_array = 1;     //实型数组
    required int32 real_count = 2;      //实型数组大小
    repeated int32 int_array = 3;       //整型数组
    required int32 int_count =4;        //整型数组大小
}

在当前位置打开命令窗口,输入命令:
.\protoc --cpp_out=Generate dataClass.proto
在Generate文件夹内生成了dataClass.pb.h和dataClass.pb.cc文件,将这两个文件加入到工程中,将proto源码目录protobuf_3.7.x/src添加到工程配置的附加包含目录,并将libprotoc.lib和libprotobuf.lib添加到附加依赖项中。

protobuf-net

protobuf-net工具获取

protobuf-net源码的Github地址如下:
https://github.com/mgravell/protobuf-net
可以选择直接克隆master分支,或者在release中获取发布出的版本,目前最新的release版本是2.3.5,地址为:
https://github.com/mgravell/protobuf-net/releases?after=2.3.11
该地址可以获取编译好的应用程序压缩包protogen.1.0.0.zip,也可以下载对应版本的源文件。下载protogen.1.0.0.zip并解压,其中包含一个Release文件夹,Release文件夹内容如下图所示。


进入到net40目录。

其中的protogen.exe就是根据*.proto文件生成*.cs文件的工具。
除此之外,还可以从GitHub上克隆master分支,在目录:
protobuf-net\src\protogen.site\wwwroot\protogen
下有多个版本的protogen压缩包,解压后目录结构与release中获取的protogen.1.0.0.zip一样。
或者根据源码自行编译处protogen.exe。

用 *.proto 生成 *.cs

下面用一个示例说明如何将*.proto转换为*.cs:
假设我的protogen.exe位于E:\protogen 1.0.0,如下图所示:



在此文件夹中创建一个文件“student.proto”,用记事本打开,添加内容:

message Student{
    required string name = 1;   //名称,字符串类型
    required double gender = 2; //性别,bool类型(取值0或1)
    required int32 age = 3;        //年龄,整型
    repeated double telephone =4; //电话号码,字符串数组
} 

保存文件,在此文件夹中创建一个文件夹Generate作为输出文件夹,如图:



在当前位置打开cmd或powershell窗口,输入命令:

.\protogen --csharp_out=.\Generate student.proto

在Generate文件夹内生成.cs文件


附:proto语法

proto语法由proto2和proto3两个版本,以下内容适用于proto2

proto文件字段规则类型

required:表示后面的数据是必须的。
optional:表示后面数据是可选的。
repeated:表示后面的数据是一个数组。

proto文件标量数值类型
proto类型 Java 类型 C++类型 备注
double double double
float float float
int32 int int32 使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint32。
int64 long int64 使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint64。
uint32 int[1] uint32 Uses variable-length encoding.
uint64 long[1] uint64 Uses variable-length encoding.
sint32 int int32 使用可变长编码方式。有符号的整型值。编码时比通常的int32高效。
sint64 long int64 使用可变长编码方式。有符号的整型值。编码时比通常的int64高效。
fixed32 int[1] uint32 总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。
fixed64 long[1] uint64 总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。
sfixed32 int int32 总是4个字节。
sfixed64 long int64 总是8个字节。
bool boolean bool
string String string 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。
bytes ByteString string 可能包含任意顺序的字节数据。
关于proto文件的参考资料

官方文档
CSDN:proto3语法指南
CSDN:C# protobuf的使用方法

在C#工程中使用*.cs

只需要将上一步生成的myproto.cs加入到工程里,并且将protobuf-net.dll文件添加引用即可。
示例程序:(对上一步生成的student.cs文件的调用)

using ProtoBuf;
using System;
using System.IO;

namespace UnityUDPClient
{
    class Program
    {
        static void Main(string[] args)
        {
            //实例化一个Student对象
            Student yiya = new Student();
            yiya.Name = "yiya";
            yiya.Gender = 0;
            yiya.Age = 30;
            yiya.Telephones.Add("000");
            yiya.Telephones.Add("111");
            yiya.Telephones.Add("222");

            //序列化
            MemoryStream ms = new MemoryStream();
            Serializer.Serialize<Student>(ms, yiya);
            byte[] data_yiya = ms.ToArray();


            //反序列化
            MemoryStream ms1 = new MemoryStream(data_yiya);
            Student yiya2 = Serializer.Deserialize<Student>(ms1);

            Console.ReadKey();
        }
    }
}

在Unity(或其他C#项目)中使用 *.cs

将上一步生成的myproto.cs拷贝到Assets目录下,再将protobuf-net.dll拷贝到Assets下的Plugin文件夹。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容