博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Erlang使用ProtoBuffer
阅读量:7257 次
发布时间:2019-06-29

本文共 1868 字,大约阅读时间需要 6 分钟。

最近有工作需要打算为项目服务器做一个机器人,测试测试压力,根据自己的经验,使用Erlang来做是最合适不过的了,但是服务器使用的C++语言,使用了Google的ProtoBuffer作为协议进行数据交换,而Erlang并没有官方的Protobuffer版本支持,官方仅支持C++,JAVA,Python等几种比较主流的语言。在网上搜索了一下,ProtoBuffer的第三方Erlang版本主要有以下几个:

我使用了一下其中的一两个版本,但是发现有的对import的支持很有限,甚至不支持,而项目中的PB是有用到,最后选定第四个版本gpb,这个版本可以使用项目中的大部分proto文件生成Erlang源文件,仅有import引用的类型有引用前缀的时候不支持。举个例子:

假如现在有两个proto文件,A.proto和B.proto,A.proto中定义了一个枚举:

package A; enum Type{    T_A = 0;    T_B = 1;}

 B.proto中引用了这个枚举:

message M_Test{    required A.T_A eType = 1;    optional int32  other = 2;}

 这个时候编译proto文件,会出现如下错误:

in msg M_Test, field eType: undefined reference  A.T_A

但是如果将B.proto中的消息定义改为:

message M_Test{    required T_A eType = 1;    optional int32  other = 2;}

则能够成功编译通过。

为了解决这个问题,研究了一下gpb的源码,在gpb_parse.erl中有一个函数:

%% -> {found, {msg,FullName}|{enum,FullName}} | not_foundresolve_ref(Defs, Ref, Root, FullName) ->    case is_absolute_ref(Ref) of        true  ->            FullRef = ensure_path_prepended(Root, Ref),            find_typename(FullRef, Defs);        false ->            PossibleRoots = compute_roots(FullName),            find_ref_rootwards(PossibleRoots, Ref, Defs)    end.

这个函数是专门用来解析引用的,其中的变量Ref在第一种写法,其值为:['A','.','T_A'],这个时候解析不了;而第二种方式的写法其值为:['T_A']

如果匹配一下第一种写法的值,然后将之改为第二种写法的值,即可正常编译。为此我加了一个过滤函数如下:

filterRef([_,'.',Type]) -> [Type];filterRef(Other) -> Other.

 然后把resolve_ref函数改为:

%% -> {found, {msg,FullName}|{enum,FullName}} | not_foundresolve_ref(Defs, Ref0, Root, FullName) ->    Ref = filterRef(Ref0),    case is_absolute_ref(Ref) of        true  ->            FullRef = ensure_path_prepended(Root, Ref),            find_typename(FullRef, Defs);        false ->            PossibleRoots = compute_roots(FullName),            find_ref_rootwards(PossibleRoots, Ref, Defs)    end.

这样,就可以正常的编译项目中所有的Proto文件了。

btw,按gpb官方的介绍来看,其支持proto2以及proto3的语法,但不知道是否完全支持,有待验证。

转载于:https://www.cnblogs.com/witton/p/6858117.html

你可能感兴趣的文章
JRadioButton 实现图片切换
查看>>
图片和字符串相互转换
查看>>
动态规划,Dijkstra算法,A*算法的比较
查看>>
[笔记]sql server 单用户切换
查看>>
ios专题 - 图片(UIImage)获取方法
查看>>
iOS应用性能调优的25个建议和技巧
查看>>
LINUX常用命令--基础篇(一)
查看>>
JS查询class的名称
查看>>
web框架
查看>>
Tomcat访问日志详细配置
查看>>
栈溢出防御——windows安全机制GS编译选项
查看>>
《Programming in Lua 3》读书笔记(十四)
查看>>
PBOC~PPT-补充A(转)
查看>>
项目中经常使用的JS方法汇总,非常有用
查看>>
Nginx 1.5.2 + PHP 5.5.1 + MySQL 5.6.10 + Phalcon + Thrift + Composer在 CentOS 下的编译安装
查看>>
jQuery中工厂函数
查看>>
nexus 3上次jar包
查看>>
openstack oslo.messaging库
查看>>
探索c#之不可变数据类型
查看>>
python字符串操作
查看>>