C++ 使用 google Protobuf 2 和 protobuf3 依赖项?

Posted

技术标签:

【中文标题】C++ 使用 google Protobuf 2 和 protobuf3 依赖项?【英文标题】:C++ use google Protobuf2 with protobuf3 dependencys? 【发布时间】:2021-08-28 20:15:39 【问题描述】:

我有一个使用Google Protobuf2 的项目。现在我想使用通过 CMake 集成的预构建 tensorflow C-API。但现在我收到以下错误:

libprotobuf FATAL google/protobuf/stubs/common.cc:61] 这个程序需要 3.9.0 版本的 Protocol Buffer 运行时库,但安装的版本是 2.6.1。请更新您的图书馆。如果您自己编译程序,请确保您的标头来自与链接时库相同的协议缓冲区版本。 (“bazel-out/k8-opt/bin/tensorflow/core/framework/tensor_shape.pb.cc”中的版本验证失败。) 在抛出 'google::protobuf::FatalException' 的实例后调用终止 what():这个程序需要3.9.0版本的Protocol Buffer运行库,但是安装的版本是2.6.1。请更新您的图书馆。如果您自己编译程序,请确保您的标头来自与链接时库相同的协议缓冲区版本。 (“bazel-out/k8-opt/bin/tensorflow/core/framework/tensor_shape.pb.cc”中的版本验证失败。)

有没有简单的方法来解决它? Tensorflow 不与项目的其余部分交换任何消息,所以我可以保留两个版本吗?降级 tensorflow proto 是不可能的,因为它是一个预构建的库。将项目的其余部分升级到 proto3 也需要付出很多努力。我可以只使用 proto 3.9.0 并将 syntay="proto2" 添加到所有旧的 proto 文件吗?

【问题讨论】:

在最坏的情况下,您也许可以使用 dlopenRTLD_LOCAL 来相互“隐藏”库。不过,这很痛苦,因为您必须手动访问绑定您使用的每个符号;如果您实际上 dlopen 您自己应用程序的另一部分,这可能是最简单的,这样您就可以简化边框。 @o11c 我认为您的解决方案是正确的!你能告诉我在哪里以及如何使用 dlopen() 吗? 你读过dlopen man page吗? (请注意,dlmopen 并不能真正帮助您;当您需要多个库相互了解但不了解其他库集时,它很有用)。使用x macros(单独的文件版本更合理)来维护要跨库边界导入的符号集可能很有​​用,如果这是您自己的事情,这会容易得多,但不是绝对必要的。 @o11c 是的,只是有一点我不明白的词汇。所以就我而言:我有 tensorflor-c-api 由一些标头和一些二进制文件 (.so) 组成。不,我有一个 c++ 包装器可以在我的包中使用 tensorflow-C-Api。现在我必须在哪里加载动态共享对象?在我的 cpp-wrapper 标头中?而且我真的需要将 handlerto 放在每个使用 tensorflow 函数的函数之前吗? 【参考方案1】:

架构语言和运行时是分开的。更多:如果您不添加显式语法标记,则 proto2 保持默认,因此 严格来说您根本不需要更改 proto 文件,尽管它会发出警告,建议您添加语法标记。在这种情况下,是的:只需添加 syntax="proto2";

但是请注意,发出的代码中可能还有其他 API 更改,但这应该是相对较小的。

【讨论】:

谢谢!但现在我收到以下错误:退出代码 139(被信号 11 中断:SIGSEGV) @Emilio7773 段错误?我无法仅通过评论来诊断(另外:虽然我对 protobuf 了解很多,但 C/C++ 不是我的主要语言) 我刚刚发现这个:github.com/tensorflow/tensorflow/issues/41080 我认为这正是问题所在。我现在唯一的解决方案是使用带有 RTLD_DEEPBIND 标志的 dlopen 在我的应用程序中加载 libtensorflow。但我不知道这是什么意思 @Emilio7773 RTLD_DEEPBIND 处于“可怕且可能以难以理解的方式破坏事物”的领域。首先,您真的不希望出现不受控制的符号冲突;我对RTLD_LOCAL 的建议完全避免冲突(当它失败时,它会以一种理智的方式失败)。

以上是关于C++ 使用 google Protobuf 2 和 protobuf3 依赖项?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中的 Google ProtoBuf 与 C# (UDP) 中的 Protobuf-net 聊天

Protobuf C++ 与 Android Java

由于 C++ 而解决 Google protobuf 中的枚举字段命名限制的解决方案

不同版本的 google protobuf 可以一起工作吗?

C++ google protobuf:如何从扩展的 FieldDescriptor 创建 MutableExtension

在 C++ 中更改现有 protobuf 消息的元素