使用 proto3 编译器编译 proto2 语法文件

Posted

技术标签:

【中文标题】使用 proto3 编译器编译 proto2 语法文件【英文标题】:Compiling proto2 syntax file with proto3 compiler 【发布时间】:2018-07-15 07:01:32 【问题描述】:

我有一个用 proto2 语法编写的 proto 文件。我正在使用 proto3 编译器编译这个 proto 文件。虽然它构建成功,但它在运行时显示以下错误。谁能帮帮我。

[libprotobuf FATAL google/protobuf/extension_set.cc:102] 类型“x.y.z.a”的多个扩展注册,字段号 200。 在抛出 'google::protobuf::FatalException' 的实例后调用终止 what():类型“x.y.z.a”的多个扩展注册,字段编号为 200。

【问题讨论】:

【参考方案1】:

错误表明,不知何故,您的程序有此扩展的定义的两个副本。这可能不是 protoc 的错,而是您的程序构建方式中的一些错误。

这是我的理论:您的 proto 文件已被单独编译并链接到两个不同的组件/库中,然后它们都被加载到同一个程序中。其中一个组件是您的,另一个是共享相同协议的其他组件。另一个组件之前已经在使用 protobuf 3.5.1,但您的组件使用的是 2.3.0。这意味着您的程序中实际上有两个 libprotobuf 副本。因此,扩展的两个副本是使用不同的 libprotobuf 副本加载的,因此没有错误。但是现在您已将组件切换为使用 protobuf 3.5.1,因此现在只加载了一个 libprotobuf 副本,并且将 proto 文件的两个副本都加载到该 libprotobuf 副本中。所以现在,你得到一个错误。

要解决此问题,您需要确保您的程序包含每个 proto 文件的一个已编译副本。如果两个组件需要共享一个协议,则需要将该协议分解为一个单独的组件以进行共享。

【讨论】:

【参考方案2】:

听起来您有一条消息 x.y.z.a,并且您在多个地方定义了一个 id 为 200 的扩展。

所以是这样的:

package x.y.z;
message a 
    extensions 200 to 255;


extend a 
    optional int32 foo = 200;


extend a 
    optional int32 bar = 200;

因此请检查此类重复的扩展名,这些扩展名可能定义在多个文件中。

【讨论】:

检查了代码。没有这种东西。还只想提一下,它运行良好,并且在使用 protoc 版本 2.3.0 时不会出现此错误,但是当使用 protoc 版本 3.5.1 编译时,它会在尝试运行时出现此错误

以上是关于使用 proto3 编译器编译 proto2 语法文件的主要内容,如果未能解决你的问题,请参考以下文章

Go

protobuf 学习 收藏的文章

Golang里面使用protobuf(proto3)

深入protoBuf

protobuf介绍和语法

protobuf介绍和语法