首页 > 解决方案 > Protobuf 对象在传递给动态库时被损坏

问题描述

我正在将我的库与一些深度学习框架集成在一起,但遇到了一些内存问题。我怀疑 protobuf 是这里的问题,但我想征求你们的意见和一些帮助,因为我已经花了太多时间在这上面。简而言之,该框架在 ONNX 格式的深度学习模型上运行。它将它们读入内存中的onnx::ModelProto对象。然后将这些对象传递给我的库,在那里它们被转换(和优化)为我的自定义表示并返回到框架。是从https://github.com/onnx/onnx/blob/master/onnx/onnx.protoonnx::ModelProto生成的 C++ 类- 一个常规的 protobuf 消息。protoc

ModelProto到达我的图书馆时会出现问题。的主要成员ModelProto是图,它是一个指针:onnx::GraphProto* onnx::ModelProto::graph_. 当对象被传递到我的库时,图形指针被设置为一些不同的地址,这不是正确的GraphProto对象位置:

framework:
model_proto: 0x2ccb450
graph address: 0x2cc1d20
---
mylib:
model_proto: 0x2ccb450
graph address: 0x7fb6529c2560

烦人的事情是它只发生在发布版本中。当我在调试中编译两者时 - 它可以正常工作。

此外,在出现此错误之前,我ModelProto使用std::stringstream- 我首先将框架中的模型序列化为字符串,从中创建一个流并在我的库中反序列化。反序列化完成后,图表也被破坏了,这太糟糕了,以至于我的代码中进一步出现了段错误。

这与框架和我的库都与它们自己的 protobuf 副本静态链接这一事实有关吗?Protobuf 作为依赖项添加,并与框架和我的库一起编译。我确保我使用相同的版本(目前是 3.11)。我也使用相同的 ONNX 版本(1.6)。

以下是依赖项和工作流程的外观:

依赖关系

标签: c++memoryprotocol-buffersonnx

解决方案


由于 C++ 中没有标准的 ABI,因此在单独构建的库之间传递对象的门槛非常高。

使用 protobuf 的全部原因是将对象转换为字符串,然后在两个端点之间交换这些字符数组。这样,您就可以解决围绕具有不同布局、格式、精度、字节序的对象的所有问题。

如果您绝对想传递指针,则构建设置必须相同。一切。所有编译器和链接器版本、设置、所有#defines、优化级别等......这是一条非常难以遵循的路径,并且是一个脆弱的解决方案。


推荐阅读