我正在将我的库与某些深度学习框架集成在一起,并且遇到了一些内存问题。我怀疑protobuf是这里的问题,但我想请大家征求意见和帮助,因为我已经花了太多时间。简而言之,该框架适用于ONNX格式的深度学习模型。它将它们读取到内存中,成为onnx::ModelProto
对象。这些对象然后被传递到我的库,在那里它们被转换(并优化)为我的自定义表示形式,并返回到框架。 onnx::ModelProto
是从https://github.com/onnx/onnx/blob/master/onnx/onnx.proto(常规protobuf消息)中的protoc
生成的C++类。
当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++中没有标准的ABI,因此在单独构建的库之间传递对象的标准很高。
使用protobuf的全部原因是将对象转换为字符串,然后在两个端点之间交换那些字符数组。这样,您可以解决围绕具有不同布局,格式,精度,字节序的对象的所有问题。
如果您绝对要传递指针,则构 build 置必须相同。一切。所有编译器和链接器版本,设置,所有#define,优化级别等...这是一条很难遵循的路径,并且使解决方案变得脆弱。
关于c++ - Protobuf对象在传递给动态库时损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61480899/