如何将ProtoBuffer生成Erlang文件
ProtoBuffer官方提供了C++、Java、Python等语言的生成器,但不支持Erlang语言,为了让Erlang也可以使用ProtoBuffer,需要下载一个第三方生成工具。我这里使用的是gbp。
1.安装git工具,并将git下的bin目录添加到path路径中。
2.安装mingw,并添加到path路径中。
3.从 https://github.com/tomas-abrahamsson/gpb中checkout源码。
4.进入到gpb根目录,直接make进行编译。另外一种编译方式是使用rebar,需要下载rebar工具,可以直接下载到gpb的根目录然后使用escript rebar compile指令编译。
5.编译我们的ProtoBuffer文件,假定我们将ProtoBuffer文件XX.proto复制到gpb/bin目录下,并在此目录下创建一个pb目录,我们在gpb/bin目录中再创建一个批处理来生成Erlang文件,批处理文件compile.bat内容如下:
1escript protoc-erl -I. -o ./pb XX.proto
2pause```
3
4
5该命令会将生成的Erlang文件放到gbp/bin/pb目录中。这是只有一个PB文件的情况,在实际项目中,我们一般会有多个PB文件,这些PB文件可能还会有依赖关系,比如我们有两个PB文件XX.proto和YY.proto:
6
7YY.proto:
8
9
package Protocol;
option optimize_for = LITE_RUNTIME; option cc_generic_services = false;
enum EValue { VA = 0; VB = 1; VC = 2; VD = 3; };```
XX.proto:
1package Protocol;
2
3import "YY.proto";
4
5option optimize_for = LITE_RUNTIME;
6option cc_generic_services = false;
7
8message Msg
9{
10 YY.EValue v1 = 1;
11 int32 v2 = 2;
12};
这个时候运行compile.bat,会产生一个错误:
1in msg Msg, field v1: undefined reference YY.EValue```
2
3
4
5 说明目前的gpb还不支持具有依赖关系的PB,为了解决这个问题,我对源码进行了调试,发现gpb在解析PB文件时并没有去处理依赖关系,既然没处理依赖,那我们加上依赖的处理即可。找问题需要花时间,只要找到问题的根源了,解决起来也许就是一小段代码就可以解决的事情。经调试查找,gpb解析PB源文件的源码在gpb_parse.yrl文件中,而解决PB依赖关系的代码是由:
6
7
8
9
resolve_ref(Defs, Ref, Root, FullName)```
函数处理的,我们只需要加一个解决依赖的代码,然后在上面的函数中调用一下即可,完整代码如下:
1filterRef([_,'.',Type]) -> [Type];
2filterRef(Other) -> Other.
3
4%% -> {found, {msg,FullName}|{enum,FullName}} | not_found
5resolve_ref(Defs, Ref0, Root, FullName) ->
6 Ref = filterRef(Ref0),
7 case is_absolute_ref(Ref) of
8 true ->
9 FullRef = ensure_path_prepended(Root, Ref),
10 find_typename(FullRef, Defs);
11 false ->
12 PossibleRoots = compute_roots(FullName),
13 find_ref_rootwards(PossibleRoots, Ref, Defs)
14 end.```
15
16
17
18
19现在执行**compile.bat**就不会报错了,可以在gpb/bin/pb目录下看到四个文件。
20
21
22
23
24
25Btw:写完本博客才发现之前有写过一类似的博客,当时CSDN无法登录,在博客园写的,参见:[https://www.cnblogs.com/witton/p/6858117.html](https://www.cnblogs.com/witton/p/6858117.html)
26
27
28
29祝玩得开心!
30
31
32
33
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2017/2017-11-27-如何将ProtoBuffer生成Erlang文件/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。