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