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

protobuf、protobuf-net系列库的源码编译以及使用方法_第1张图片

编译生成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

protobuf、protobuf-net系列库的源码编译以及使用方法_第2张图片

点击Configure,选择生成VS工程的版本,如下图
protobuf、protobuf-net系列库的源码编译以及使用方法_第3张图片

选择Visual Studio 15 2017即编译VS2017 win32工程,选择Visual Studio 15 2017 Win64即编译VS2017 win64工程。
若提示无法找到ZLIB,则在窗口中找到下图这三个变量名,设置值
protobuf、protobuf-net系列库的源码编译以及使用方法_第4张图片

ZLIB_INCLUDE_DIR即zlib源码路径
ZLIB_LIBRARY_DEBUG和ZLIB_LIBRARY_RELEASE分别对应上文编译好的库文件zlibwapid.lib和zlibwapi.lib(注意,若要生成VS win64工程要选择64位的库文件,VS win32工程则选择32位的库文件)
配置好以后,再次点击Configure,如下图:
protobuf、protobuf-net系列库的源码编译以及使用方法_第5张图片

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

用VS工程编译protubuf

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

protobuf、protobuf-net系列库的源码编译以及使用方法_第6张图片

受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目录。
protobuf、protobuf-net系列库的源码编译以及使用方法_第7张图片

其中的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,如下图所示:


protobuf、protobuf-net系列库的源码编译以及使用方法_第8张图片

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

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

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


protobuf、protobuf-net系列库的源码编译以及使用方法_第9张图片

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

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

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


protobuf、protobuf-net系列库的源码编译以及使用方法_第10张图片

附: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(ms, yiya);
            byte[] data_yiya = ms.ToArray();


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

            Console.ReadKey();
        }
    }
}

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

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

你可能感兴趣的:(protobuf、protobuf-net系列库的源码编译以及使用方法)