当前位置: 首页 > 知识库问答 >
问题:

正在阅读的评论。使用协议缓冲区描述符对象的proto文件

邓卓
2023-03-14

我目前正在重新访问一个使用Google协议缓冲区的项目。

在项目中,我想利用协议缓冲区的特性描述符和反射。

官方文件指出,的注释。可以读取proto文件:

  1. 使用对消息或描述符调用的函数DebugStringWithOptions()
  2. 使用对描述符调用的函数GetSourceLocation()

我无法检索注释,所以我认为我做了一些完全错误的事情,或者该功能尚未在协议缓冲区中完全实现。

以下是一些代码片段:

google::protobuf::DebugStringOptions options;
options.include_comments = true;
std::cout << "google::protobuf::Descriptor::DebugStringWithOptions(): "
          << message.descriptor()->DebugStringWithOptions(options) << std::endl
          << std::endl;

const google::protobuf::FieldDescriptor* field_descriptor{
    message.descriptor()->field(1)};

// TODO(wolters): Why doesn't this work?
google::protobuf::SourceLocation* source_location{
    new google::protobuf::SourceLocation};
field_descriptor->GetSourceLocation(source_location);

// if (field_descriptor->GetSourceLocation(source_location)) {
std::cout << "start_line: " << source_location->leading_comments
          << std::endl;
std::cout << "end_line: " << source_location->leading_comments << std::endl;
std::cout << "start_column: " << source_location->start_column << std::endl;
std::cout << "end_column: " << source_location->end_column << std::endl;
std::cout << "leading_comments: " << source_location->leading_comments
          << std::endl;
std::cout << "trailing_comments: " << source_location->trailing_comments
          << std::endl;
// }

我已经尝试在<代码>中对注释使用以下两种语法。proto文件,但它们似乎都不起作用:

MessageHeader header = 1;  // The header of this `Message`.

/**
 * The header of this `Message`.
 */
MessageHeader header = 1;

我使用的是GCC 4.7.1(启用了C 11支持)和最新的协议缓冲区版本3.0.0-alpha-4.1。

是否有人可以引导我进入正确的方向和/或为我提供一个工作示例?

编辑2015-09-24:

在官方文档中重新设置了自我描述消息部分并测试了大量内容之后,我似乎对protobuf描述符有了更好的理解。

如果以下一个或多个陈述不正确,请更正:

  1. 只有在另一端不知道的情况下,selfdescripingmessage协议才有用。原型定义

在我看来,实现这一目标的唯一途径是:

>

--include_imports --include_source_info and --descriptor_set_out=message.desc

message.desc文件与应用程序/库一起发布,以便能够在运行时读取它(见下文)。

这对我来说似乎很复杂,所以我还有两个问题:

  1. 难道没有一种不使用FileDescriptorSet就可以包含源信息的方法吗

编辑2015-09-25:所谓上帝类,我的意思是消息类和/或描述符类提供了或多或少无用的公共功能,因为它们在客户端使用时不提供任何信息。以“普通”消息为例:因此生成的代码不包含源注释信息,因此所有描述符类(例如,描述符和字段描述符)中的GetSourceLocation方法完全无用。从逻辑角度来看,如果处理消息和描述符,则应提供单独的实例,如果处理来自文件描述符集(其源通常是从.proto文件生成的.desc文件)的信息,则应提供单独的实例。A<代码>[…]Lite类将成为“普通”类的父类。关于protoc可能永远不会包含源代码注释的论点强调了我的观点。

“连接”是指使用来自的描述符信息更新消息中的描述符信息的API函数。desc文件(如果我理解正确,它总是消息提供的描述符的超集)。

共有1个答案

欧阳何平
2023-03-14

听起来你基本上已经明白了。

您将深入了解协议编译器内部的API,这些API并不是真正为公众使用而设计的。它变得复杂了,因为没有人编写帮助层来简化事情,因为没有多少人使用这些功能。

我不知道你所说的“上帝阶层”是什么意思<代码>消息仅仅是protobuf实例的抽象接口。描述符描述protobuf实例的类型<代码>消息::getDescriptor()返回消息的类型,但除此之外,这些API之间没有太多直接连接。。。

是否有一种方法可以在不使用FileDescriptorSet的情况下包含源信息?

注释故意从嵌入到生成代码中的描述符中剥离出来,因此需要单独运行解析器,生成描述符集,并动态使用它。

是否可以使用具体的消息类/实例“连接”/设置FileDescriptorSet,因为这将大大简化事情?

您的意思是希望Message::getDescriptor()返回包含源文件中注释数据的描述符吗?这将要求将注释数据嵌入生成的代码中,这对于protoc实现来说是微不足道的(它目前有意将它们去掉,所以它只能不这样做),但可能会膨胀和危险(可能会泄露使用protobufs构建的封闭源代码二进制文件的用户的秘密)。

 类似资料:
  • 我的目标是用扩展名解析协议缓冲区文件。pb。一串在Mac上使用自制软件下载Protobuff。运行protoc--版本,并具有libprotoc 3.1.0版本。 但当我运行Python时,它会说找不到模块。我改变了主意。pb文件名到\u pb2。py并在Python脚本中导入模块。 我正在使用谷歌文档,但仍然没有任何运气。我在编译Protobuf时也遇到了问题。so文件通过Python。我只是无

  • 问题内容: 我正在尝试动态解析Java中的给定.proto文件,以解码Protobuf编码的二进制文件。 我有以下解析方法,其中“ proto”字符串包含.proto文件的内容: 但是,执行时,先前的方法将引发消息“协议消息标签的电线类型无效”的异常。我使用了来自Google的示例.proto文件,因此我认为它是有效的:https : //github.com/google/protobuf/bl

  • (见底部更新) Tilemaker是一个OpenStreetMap程序,用于从OSM pbf数据文件生成Mapbox矢量图块(其本身就是协议缓冲区(pbf)文件)。我已经编译了它,并用它创建了一个矢量平铺目录。我无法用Python解析这些文件。 我使用以下内容创建了矢量平铺: 然后,我以Google的Protocol Buffers python教程为基础,以这种方式创建了一个简单的python程

  • 我正在使用模拟开放框架架构SOFA(语言),我的目标是在一些沙发源本机数据与其他外部应用程序之间设置一些通信类型。按照这个顺序,我使用ZeroMQ将沙发数据传输到python外部应用程序。 在SOFA( 文件,以下字段:,,? 目前,文档中不清楚如何定义与向量和其他数据类型相关的字段,如SOFA原生的(四元数)。 Vec3d和Quat由以下元素组成: 是否可以定义为枚举数? 更新 目前,我的暂定仪

  • 问题内容: 我的一位同事提出了在运行时生成协议缓冲区类的想法。含义: 有C ++服务器应用程序和Java客户端应用程序通过TCP / IP通过协议缓冲区消息进行通信。 C ++应用程序在不同版本中可能具有不同的架构,并且不一定向后兼容 有与此服务器通信的Java应用程序,该应用程序应支持所有可能的服务器版本。 这个想法是服务器将协议缓冲区的定义作为初始握手的一部分发送,并且Java应用程序在运行时

  • 我知道协议缓冲区是一种序列化格式,需要中的消息格式。proto,以便正确读回。但我有一个文件,我不知道正确的消息格式,因为它没有发布。我想做的是自己对数据进行反向工程,这样我就可以重建消息。为此,我需要读取原始文件,从中可以提取字段编号、类型和值。 有没有一个程序可以做到这一点(最好是在python中,但C/C也很酷)?