从微信SDK看ProtoBuffer文件的生成
前言
Protocol Buffers (下面简称PB)是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。它支持多种语言,比如C++,Java,C#,Python,JavaScript等等。目前它的最新版本是3.0.0。与PB经常相提并论的也是Google推出的FlatBuffers(下面简称FB)。有关PB和FB性能和语义等方面的区别,这里就不展开描述了。如果有兴趣,可以参阅下面的信息:
目前很多公司在一些高性能的通信场景下,会越来越多的选择用PB或者FB来替代我们常用的Json。比如说Windows Phone的微信的SDK就用到了。
反编译微信SDK
PB对C#官方的支持是从3.0开始的,之前的1.0和2.0的版本都能找到一些非官方的版本。我们先反编译一下微信的SDK,看下它具体是什么版本的。
首先,我们从微信的官网下载SDK:

登陆微信开发平台,进入资源中心,选择WP8资源下载,点击下载。
然后下载我们的反编译工具ILSpy。
解压下载完成的ILSpy和SDK包,用ILSpy.exe打开MicroMsgSDK.dll。

我们暂时先不管这个结构到底是怎么来的,我们可以看到反编译出来的文件带了ProtoGen的版本号,我们尝试从Github上找到这个版本号的代码。
编译ProtoBuffer源码
我们先打开官方的C#版本的PB的源码页面:地址。
可以看到官方地址只保留了3.0的版本,对于旧的2.0版本的代码在jskeet的账号下,

我们点开这个仓库,然后找到它的Release页面:

我们找到2.3.0.277的源码并下载到本地。
解压文件,我们看到Build文件夹下有一堆编译用的脚本:

双击运行buildAll.bat(此处应确保本机已经安装了Visual Studio 2008及以上版本),然后等待编译完成。
尝试使用源码中的Proto文件生成cs代码
我们找到ProtoGen项目中生成的exe文件,尝试将它放到命令行中运行:

它提示我们找不到protoc.exe程序。我们回到源码的根目录会发现有一个lib的文件夹,里面有一个protoc.exe的程序。所以我们尝试吧ProtoGen项目的所有生成文件拷贝到lib下。
继续尝试运行我们的ProtoGen程序。

这回对了,我们尝试把源码下的protos文件夹下的三个子文件夹拷贝到我们的lib目录下。
我们尝试输入如下内容:
protogen --proto_path==protos protos/tutorial/addressbook.proto
又得到一个错误信息:

提示我们找不到依赖,我们尝试打开proto文件:(有关PB的语法请参阅:http://www.cnblogs.com/stephen-liu74/archive/2013/01/02/2841485.html)
package tutorial;
import "google/protobuf/csharp_options.proto";
option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.Examples.AddressBook";
option (google.protobuf.csharp_file_options).umbrella_classname = "AddressBookProtos";
option optimize_for = SPEED;
message Person {
required string name = 1;
required int32 id = 2; // Unique ID number for this person.
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person person = 1;
}
我们可以看到导入了google/protobuf/csharp_options.proto文件,我们回头看protogen的命令参数中有一个import的标记,我们尝试添加:
protogen --proto_path==protos protos/tutorial/addressbook.proto --include_imports=google/protobuf/csharp_options.proto
没有任何错误,并且我们在lib的目录下发现了生成的cs文件。

从cs文件反推proto文件
我们打开AddressBookProtos文件,阅读源码发现:
只有两个非静态类,与我们Proto文件中的Person和AddressBook对应:

Person类中又有一个嵌套的枚举和类,与PhoneType和PhoneNumber对应:

我们有发现,在类的IsInitialized中,Name和Id等required的有是否有值得判断,所以我们能区分去required和optional

其他依赖信息,我们可以通过引用来查找。
从反编译的微信文件中反推proto文件
我们以BaseReqP为例。首先,没有using,所以我们确定没有其他的Proto文件的依赖。我们只发现一个类,所以说明它只有一条message,名称就是BaseReqP,然后包名是MicroMsg.sdk.protobuf。
我们知道message的所有字段是需要标记数字的:

从这里我们又反推出,message有两个字段:Transaction和Type,它们类型分别是string和uint。
接下来我们推是否是必须的。找到我们的IsInitialized:

从这里我们就知道了两个字段都是必须的。所以综合上述信息,我们可以写出的proto文件如下:
package MicroMsg.sdk.protobuf;
message BaseReqP {
required uint32 Type = 1;
required string Transaction = 2;
}
小结
本篇内容简要介绍了ProtoBuffer的文件如何生成C#文件,并简单的举例如何从C#文件反推Proto文件。
参考信息
- FlatBuffers Documentation
- Google Protocol Buffer 的使用和原理
- Protobuf Source
- protocol-buffers documentation
- Google序列化库FlatBuffers 1.1发布,及与protobuf的比较
- FlatBuffers与protobuf性能比较
- Protocol Buffer使用简介
- Protocol Buffer技术详解(语言规范)
从微信SDK看ProtoBuffer文件的生成的更多相关文章
- 【Win10 UWP】微信SDK基本使用方法和基本原理
上回讲到,作为一个长期散播温暖,散播希望的小清新无公害WP开发者,继QQ SDK之后,又把UWP微信SDK这茬了结了,仅供学习交流. 1.安装微信SDK for UWP 微信官方此前明确说明短时间内暂 ...
- 微信公众平台开发,图文回复、access_token生成调用、以及微信SDK的实现(2)
上一节课,我给大家分享了微信API接入以及事件推送的回复,这是微信开发的第二节课,重点给说一说单图文回复,多图文回复,access_token,微信SDK. 公众号消息回复很多种形式,常见的形式有,文 ...
- Xamarin绑定微信SDK 实现分享功能
从开始做这一块的工作开始,就开始找各种的资料,最后还是老老实实的去看官方文档. 对于Xamarin.Android的绑定属于纯jar的绑定,这个难度较小,添加Bindings Library,将lib ...
- iOS-不用微信SDK唤起微信支付
作者:TianBai 原文链接:http://www.jianshu.com/p/8930b4496023 要想知道微信SDK是如何调起微信客户端,那么咱们先看看微信SDK到底做了什么 前期准备 接入 ...
- 超级懒汉编写的基于.NET的微信SDK
一.前言 特别不喜欢麻烦的一个人,最近碰到了微信开发.下载下来了一些其他人写的微信开发“框架”,但是被恶心到了,实现的太臃肿啦. 最不喜欢的就是把微信返回的xml消息在组装成实体类,所以会比较臃肿,现 ...
- Android开发中出现cannot be resolved to a variable错误,也就是R文件不能生成。
最近开始学过习Android开发,配置完成开发环境后,在创建第一个Android项目就出现了cannot be resolved to a variable错误,也就是R文件不能生成的问题. 以下是从 ...
- Xamarin Android绑定微信SDK
现在几乎所有的APP都集成了向微博,微信等社交平台分享的功能.这些社交平台官方也提供了SDK让开发者使用,对于Android和IOS平台而言,只需要下载官方的SDK,按照官方说明文档进行集成就可以轻松 ...
- 基于.NET的轻量级微信SDK
一.前言 特别不喜欢麻烦的一个人,最近碰到了微信开发.下载下来了一些其他人写的微信开发“框架”,但是被恶心到了,实现的太臃肿啦. 最不喜欢的就是把微信返回的xml消息在组装成实体类,所以会比较臃肿,现 ...
- 公众号使用微信sdk的正确姿势
当我们做微信登录授权,微信公众号的分享,微信的h5支付等等等等的时候难免会用到微信sdk,当我们用react或vue做的spa应用,直接引入后会发现,在按安卓上可以正常调试,而ios上一直报签名错误( ...
随机推荐
- R语言学习笔记—K近邻算法
K近邻算法(KNN)是指一个样本如果在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性.即每个样本都可以用它最接近的k个邻居来代表.KNN算法适 ...
- ARM汇编关键知识点总结(转)
1.LDR R1, =COUNT 意思是将 COUNT 变量的地址放到 R1中LDR R1, COUNT 意思是将 COUNT 变量地址里面的内容赋给 R1 2. Load-Store 结构——这个应 ...
- 8 功能6:后台管理页面,编辑文章,xss攻击
1.后台管理页面之文本编辑 # 后台管理url re_path(r'^cn_backend/$', views.cn_backend, name='cn_backend'), re_path(r'^c ...
- Python day2 ---python基础2
本节内容 列表. 元组操作 购物车程序 字符串操作 字典操作 3级菜单 作业(购物车优化) 1. 列表操作 1.定义列表names = ['Alex',"Tenglan",'Eri ...
- P3703 [SDOI2017]树点涂色
P3703 [SDOI2017]树点涂色 链接 分析: 首先对于询问,感觉是线段树维护dfs序,每个点记录到根的颜色个数.第二问差分,第三问区间取max. 那么考虑修改,每次将一个点的颜色变成和父节点 ...
- git删除所有提交历史记录
这种方式是最快最有效的 进项目根目录启动git bash,然后执行这些即可 最后的 git push -f origin master 会失败,直接在idea里push就能成功了 .Checkout ...
- c3p0 连接数据库失败的问题
报错:java.sql.SQLException: No suitable driver 显然,这里c3p0由于没有找到对应的配置文件(c3p0-config.xml或者c3p0.properties ...
- python爬虫之Scrapy框架(CrawlSpider)
提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬去进行实现的(Request模块回调) 方法二:基于CrawlSpi ...
- 网络设备重的loopback接口
回环接口在我们做试验的过程有典型的应用,几乎可以离不开它,一个虚拟的接口,给我带来了很大的方便,有了回环接口,你可以不用为你的PC,来添加第二块物理网卡,就可以完成VM,服务器搭建,群集,VPN等试验 ...
- C++构造函数深度探究
1.引子: 以下代码中的输出语句输出0吗,为什么? struct Test { int _a; Test(int a) : _a(a) {} Test() { Test(0); } }; Test o ...