协议缓冲区的静态链接会导致与现有符号冲突
Static linking of Protocol Buffers results in conflicts with existing symbols
我们正在尝试为C++运行时实现协议缓冲区格式 (ONNX( 导入器。我们的运行时将由前端应用程序使用,这些应用程序也使用协议缓冲区模型。
当尝试执行同时运行前端和后端组件的进程时,我们看到错误,指示符号名称conflicts with the existing symbol
。
[libprotobuf ERROR google/protobuf/descriptor_database.cc:109] Symbol name "onnx.AttributeProto" conflicts with the existing symbol "onnx.AttributeProto".
[libprotobuf FATAL google/protobuf/descriptor.cc:1164] CHECK failed: generated_database_->Add(encoded_file_descriptor, size):
terminate called after throwing an instance of 'google::protobuf::FatalException'
what(): CHECK failed: generated_database_->Add(encoded_file_descriptor, size):
Aborted (core dumped)
有没有办法让两个组件(应用程序和共享对象(静态链接 PB 消息处理代码并在一个进程中注册相同的 Protobuf 符号?有没有办法告诉另一个组件不要重新注册PB消息?
重整解决方案
协议缓冲区保存基于.proto
文件名的全局注册表。当 2 个软件尝试将相同的 PB 消息添加到此注册表时,会出现名称冲突。
解决此问题的一种方法是人为地更改 PB 消息命名空间。您可以为 PB 消息定义不同的命名空间,并依靠 CMakefile 执行符号替换和重命名。
以下是onnx-tensorrt
项目的示例:
https://github.com/onnx/onnx-tensorrt/blob/fa0964e8477fc004ee2f49ee77ffce0bf7f711a9/CMakeLists.txt#L92-L97
静态链接协议缓冲区
协议缓冲区保存基于.proto
文件名的全局注册表。当 2 个软件尝试将相同的 PB 消息添加到此注册表时,会出现名称冲突。
解决此问题的一种方法是将整个协议缓冲区库静态链接到项目。这有效地创建了一个单独的注册表,可以在其中注册 PB 消息。
以下是ngraph
项目的示例:
https://github.com/NervanaSystems/ngraph/commit/3d664abd7b8cc8295b6da79689f9bf119d55a2dd
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 写入位置0x0000000C时发生访问冲突
- 将无符号char*转换为std::istream*C++
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- vscode g++链路故障:体系结构x86_64的未定义符号
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 使用gcc从静态链接的文件中查找可选符号
- 协议缓冲区的静态链接会导致与现有符号冲突
- 使用 C++ 标准库避免共享库中的符号冲突
- 加载具有相同符号的两个共享库时是否存在符号冲突
- 将使用预处理器指令来定义美元符号表示的内容会导致任何冲突
- 内部和外部结构的符号冲突,C++ vs C
- 内存冲突:SIGSEGV 和"找不到虚拟表的链接器符号..."
- 无符号字节与换行符冲突
- "LIBCMT"与其他库的使用冲突+未解析的外部符号