Protobuf报错CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):

2023-05-16

前言

Protobuf全称Protocol buffers,是Google研发的一种跨语言、跨平台的序列化结构的数据格式,是一个灵活的、高效的用于序列化数据的协议。使用protobuf时,既可以采用动态链接,也可以采用静态链接。因为protobuf本身有一个globalregistry。每个message type都需要去那里注册一下,而且不能重复注册。所以,假如你在A.DLL中定义了某些message type,那么B.DLL就只能从A.DLL的exported的DLL interface中使用这些message type, 而不能从proto文件中重新生成C/C++代码并包含到B.DLL里去。并且B.DLL也不能私自的去修改、扩展这个message type。

最近在调用tensorRT解析onnx模型的时候使用到了这个库,遇到了一些折磨了很久的坑,记录一下。

目录

      • 前言
      • 1、运行时内存溢出
      • 2、编译时链接库报错
    • 关于`GCC`的编译选项`fpic`/`fPIC`, `fpie`/`fPIE`

1、运行时内存溢出

在代码运行时,出现以下错误

[libprotobuf ERROR google/protobuf/descriptor_database.cc:641] File already exists in database: ais_msg.proto
[libprotobuf FATAL google/protobuf/descriptor.cc:2021] CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):
terminate called after throwing an instance of ‘google::protobuf::FatalException’
what(): CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):

原因:

有人说是因为需要通信多个进程模块都集成了相同的 *.pb.cc*.pb.h 文件进行编译(动态库或者执行文件),且在编译时通过动态库 libprotobuf.so 的方式进行链接,导致在运行时报错,通过网上查找得到:**protobuf 本身有一个 global registry。每个 message type 都需要去那里注册一下,而且不能重复注册。上述的 Add 错误就是因为注册失败,原因就是因为这几个中重复注册了(多份 *.pb.cc 实现)。

PS:也有可能是protobuf的版本原因,我这里出现了这个错误之后,尝试了网上说的各种方法都没办法解决,后来把protobuf的版本从11.4.3换成6.1.3就没报这个错误了。

解决办法:静态库编译,使用 libprotobuf.a,即多个编译目标通过静态库的方式链接.

在编译protobuf的时候改 configure 文件再执行 configure

// 改成下面的样子(不同版本位置不对,所以可以搜索 ac_cv_env_CFLAGS_set)
if test "x${ac_cv_env_CFLAGS_set}" = "x"; then
 CFLAGS="-fPIC"
fi
 
if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then
  CXXFLAGS="-fPIC"
fi
$ ./configure --host=arm-linux --disable-shared CFLAGS="-fPIC -fvisibility=hidden" CXXFLAGS="-fPIC -fvisibility=hidden" --prefix=/home/auto/libSrc/protobuf-3.6.1_install
$ make -j;make install

参考:protobuf 的交叉编译使用

2、编译时链接库报错

image-20230204110551059

**原因:**报错中说我们的工程是一个动态库,但是链接的protobuf是一个静态库,将静态库编译为动态库时,会引起问题,请重新编译protobuf

**解决方法:**加上-fPIC选项重新编译protobuf库即可。

在编译protobuf的时候改 configure 文件再执行 configure

// 改成下面的样子(不同版本位置不对,所以可以搜索 ac_cv_env_CFLAGS_set)
if test "x${ac_cv_env_CFLAGS_set}" = "x"; then
 CFLAGS="-fPIC"
fi
 
if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then
  CXXFLAGS="-fPIC"
fi
$ ./configure --host=arm-linux --disable-shared CFLAGS="-fPIC -fvisibility=hidden" CXXFLAGS="-fPIC -fvisibility=hidden" --prefix=/home/auto/libSrc/protobuf-3.6.1_install
$ make -j;make install

关于GCC的编译选项fpic/fPIC, fpie/fPIE

fPIC 的全称是 Position Independent Code, 用于编译阶段,告诉编译器产生与位置无关代码,代码在被进程加载到内存时使用相对地址,所有对固定地址的访问都通过全局偏移表(GOT)来实现。

编译共享库时使用:

-fPIC: Generate position-independent code if possible (large mode)
-fpic: Generate position-independent code if possible (small mode)

编译可执行程序时使用:

-fPIE: Generate position-independent code for executables if possible (large mode)
-fpie: Generate position-independent code for executables if possible (small mode)

注:还需要在ld时增加-pie选项才能产生这种代码。即gcc -fpie -pie来编译程序。单独使用哪一个都无法达到效果。

-pie; Create a position independent executable

关于large modesmall mode的说明:small指程序必须位于2GB以下的地址空间;large指对地址空间没有任何限制。

在编译某个库的时候,加 fPIC 选项不加 fPIC 选项能否生成动态链接库没有必然的联系,即使不加 fPIC 也可以生成 .so 文件,只是对于那种库的源文件又调用了其他的地方的代码,而这个段代码在全局内存上只能有一个实例的时候,如果在多个进程中都调用了这个库那么会产生多个实例就发生了冲突,例如:Protobuf库。所以,我们在编译共享库的时候,一般都加上fPIC 编译选项,这样多个进程引用同一个 PIC 动态库时,可以共用内存。这一个库在不同进程中的虚拟地址不同,但操作系统显然会把它们映射到同一块物理内存上,这样就不会发生冲突。

对于对于不加 fPIC,则加载 .so 文件时,需要对代码段引用的数据对象需要重定位,重定位会修改代码段的内容,这就造成每个使用这个 .so 文件代码段的进程在内核里都会生成这个 .so 文件代码段的 copy。每个 copy 都不一样,取决于这个 .so 文件代码段和数据段内存映射的位置。可见,这种方式更消耗内存,但是通常来说它的加载速度会更快。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Protobuf报错CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size): 的相关文章

  • Python url请求提示certificate verify failed unable to get local issuer certificate

    python当使用requests get获取https链接时 xff0c 提示如下错误 xff1a ssl SSLCertVerificationError SSL CERTIFICATE VERIFY FAILED certificat
  • Debug Assertion Failed!解决方法详解

    1 野指针 2 内存泄露 解决方法 1 看一看你的程序里是不是有 ASSERT xff08 xff09 或 VERIFY xff08 xff09 语句 这两个宏是用来测试它的参数是否为真的 出现你说的 xff0c 这说明你的指针或表达试有问
  • Failed to execute operation: No such file or directory

    安装iptables服务 yum span class token function install span iptables services 然后再执行 xff1a systemctl enable iptables service
  • add_libraries, add_executable, target_link_libraries, link_libraries用法

    相关命令用法 add libraries将指定的源文件生成库文件 add executable将指定的源文件生成可执行文件 target link libraries跟在add xxxx后 xff0c 表示在上述两命令生成的文件后进行外部库
  • Failed to get convolution algorithm. This is probably because cuDNN failed to initialize

    Failed to get convolution algorithm This is probably because cuDNN failed to initialize from tensorflow compat v1 import
  • github代码拉取和上传出现“failed: The TLS connection was non-properly terminated”错误解决方案

    在使用VS Code上传代码到github时出现下面的错误 xff1a gnutls handshake span class token punctuation span span class token punctuation span
  • GIT代码管理: git remote add

    这里主要以 如何将一份已经写好的代码提交到两个git远端 为例 xff0c 更好地理解git remote add这句 xff1b 首先要明白一句代码的意思 xff0c 以github最经常的提示为例 xff1a 在这张图面里git ini
  • 自定义target命令:add_custom_target

    一 前置知识 1 CMake中一切都是基于target的 xff0c 如add library会产生一个library的target xff0c add executable会产生一个exe的target 2 以上命令生成的target放在
  • vs2015的OpenCV3.2.0编译

    我们希望添加第三方功能模块和库或者针对特定cpu和gpu的编译调整优化选项 这样的需求就需要自己去编译opencv了 准备东西 opencv opencv contrib cmake 还有两个文件 因为可能是国内的原因 在configure
  • protobuf快速上手

    protobuf快速上手 一 序列化与反序列化 序列化与反序列化的场景 常用的工具 二 protobuf工作原理 三 快速上手 protobuf中的数据类型 proto文件格式 编译选项 快速上手 四 通讯录demo 编写proto文件 编
  • 【Protobuf(四)】消息格式

    protobuf是一种平台语言无关的消息序列化协议 相比于传统的json xml 序列后的空间更小 但是无法自解释 需要结合额外的proto定义文件才能反序列化 当然这样也更安全 下面记录一下protobuf消息格式 protobuf消息序
  • mac环境下Maven实现ProtoBuf编译

    mac环境下Maven实现protobuf编译 1 Maven项目创建 File gt new gt Project gt 输入项目名称 gt finish 2 在项目中创建proto目录 该目录用来保存 proto文件 此处将proto目
  • Win10 下 ProtoBuf 安装编译以及在 C++ 中的用法

    ProtoBuf Protocol Buffer protoBuf 或 PB 是 google 的一种数据交换的格式 它独立于语言 独立于平台 google 提供了多种语言的实现 java c c go 和 python 每一种实现都包含了
  • protobuf详细介绍和使用

    一 protobuf初识 一 protocol buffers 是什么 protocol buffers 是一种灵活 高效 自动化机制的结构数据序列化方法 可类比 XML 但是比 XML 更小 更快 更为简单 你可以定义数据的结构 然后使用
  • protobuf的介绍、安装与使用

    1 protobuf是什么 protobuf是google旗下的一款平台无关 语言无关 可扩展的序列化结构数据格式 所以很适合用做数据存储和作为不同应用 不同语言之间相互通信的数据交换格式 只要实现相同的协议格式即同一 proto文件被编译
  • protobuf安装教程

    protobuf安装 一 Windows下安装 下载protobuf 配置环境变量 检查是否安装成功 二 Linux下安装 下载protobuf 安装protobuf 检查是否安装成功 一 Windows下安装 下载protobuf 下载地
  • 了解基本的 Git 工作流程:添加、提交、推送

    在软件开发领域 版本控制至关重要 在各种可用的版本控制系统中 Git 因其稳健性 灵活性和分布式架构而成为行业标准 在本文中 我们将重点介绍基本 Git 工作流程的基本步骤 添加 提交和推送 了解 Git 在深入研究 Git 工作流程的复杂
  • 10.netty客户端与服务器使用protobuf传输报文

    README 本文总结自B站 尚硅谷 netty 很不错 内容如下 netty的编码器与解码器 netty客户端与服务器通过 protobuf 传输报文的开发方式 文末po出了所有代码 1 netty的编码器与解码器 codec 1 编解码
  • protobuf在C#项目中的使用

    protobuf在C 项目中的使用 在C 项目中 有时候会使用到使用到protobuf来作为通信时数据交换的格式 protobuf ProtocolBuffer 简称PB 是google 的一种数据交换的格式 这是一种二进制的格式 比使用x
  • C++使用protobuf实现序列化与反序列化

    一 protobuf简介 1 1 protobuf的定义 protobuf是用来干嘛的 protobuf是一种用于 对结构数据进行序列化的工具 从而实现 数据存储和交换 主要用于网络通信中 收发两端进行消息交互 所谓的 结构数据 是指类似于

随机推荐

  • VINS 外参在线标定

    在VINS中相机的外参 R i c R ic R i c 是可以在线动态标定的 xff0c 实现函数为 xff1a 6
  • A-LOAM源码阅读

    LOAM 论文地址 xff1a https www ri cmu edu pub files 2014 7 Ji LidarMapping RSS2014 v8 pdf A LOAM地址 xff1a https github com HKU
  • LeGo-LOAM 跑通与源码学习

    论文链接 xff1a https www researchgate net LeGO LOAM 源码仓库 xff1a https github com RobustFieldAutonomyLab LeGO LOAM 本人注释 xff1a
  • SLAM中evo评估工具(用自己的数据集评估vinsFusion)

    目录 xff1a 配置标题文件修改源码修改第一处第二处第三处重新编译工程 安装evo1 安装命令2 常用指令 运行vinsFusion生成位姿估计文件使用evo评估轨迹 配置标题文件修改 主要根据自己的设备 xff0c 修改自己传感器的RO
  • Ubuntu中USB端口与外设绑定,ROS读取IMU模块数据

    目录 xff1a 1 根据设备ID绑定1 1 查看ID1 2 编写USB规则文件1 3 查看绑定结果 2 根据电脑USB口绑定2 1 找到USB端口名称2 2 编写绑定规则 3 通过ROS读数据 1 根据设备ID绑定 方法原理 xff1a
  • 实现外网Ping通WSL(网卡桥接方式实现)

    目录 xff1a 前言 xff1a 实现原理 xff1a 实现步骤1 开启hyper v2 编写桥接网络powershell脚本3 编写网络配置脚本 实现结果取消桥接最后 前言 xff1a 在我们经常和机器人打交道的这群人中有一个需求 xf
  • 如何在markdown中插入表情包

    我们平时经常使用markdown完成一些诸如博客的文档写作 xff0c 但是有时像我这种语言比较乏力的急需要在文档写作过程中插入表情包来完整的表达我想要表达的意思 xff0c 所以我去网上查了一下 xff0c 还真有 比如我想要表达开心即s
  • ROS多设备组网(WSL+miniPC+Nv Orin)

    目录 xff1a 前言硬件连接组网配置1 获取hostname和IP2 在主机添加从机的host信息3 在从机1中配置4 在从机2中配置 测试test1 话题订阅test2 rqt plot可视化传感器信息 最后 前言 实验室最近购买了两台
  • ZED 2i 双目-IMU标定

    目录 xff1a 前言IMU标定1 编译标定工具2 准备数据集3 标定 Camera IMU标定1 安装依赖2 编译Kaibr3 制作标定板下载标定板生成标定板target yaml文件 4 数据采集5 相机标定标定中遇到的问题问题1 xf
  • gazebo中给机器人添加16线激光雷达跑LIO-SAM

    目录 xff1a 前言1 下载雷达仿真包2 添加雷达支架描述文件3 添加雷达描述文件4 启动仿真5 添加IMU模块6 添加RGB D相机7 LIO SAM仿真安装依赖安装GTSAM编译LIO SAM运行 8 源码 遇到的问题1 error
  • ROS中的多线程使用

    目录 xff1a 单线程多线程订阅多个Topic xff0c 多个Spinner threads订阅一个Topic xff0c 多个Spinner threads订阅多个Topic xff0c 每个Subscriber一个Callback
  • 机器人端的图形界面ssh远程显示方案

    目录 xff1a 前言原理解析实现步骤机器人端 xff08 X client xff09 xff1a 1 安装一些必要的软件2 修改 96 etc ssh sshd config 96 中的四个地方 调试端 xff08 X server x
  • 报错 Key is stored in legacy trusted.gpg keyring

    目录 xff1a 1 找到警告相关源的key2 导出相应key到指定目录3 修改ros2源里指定加载key的路径 最近在安装ROS2的时候遇到一个关于密钥的报错 xff0c 这里记录一下 xff01 在 sudo apt update 的时
  • wsl中使用ROS工具rqt显示界面跑到窗口外面

    问题 xff1a 在WSL中使用ROS时确实会有一些小bug xff0c 比如下面这个 的rqt plot功能包时 xff0c 想通过rqt plot指令查看相应信息 xff0c 但是窗口弹出在窗口是空白的 xff0c 并且rqt那个功能界
  • RS雷达转Velodyne雷达数据Failed to find match for field ‘intensity‘

    目录 xff1a 问题分析解决 问题 因为目前很多SLAM框架支持的激光雷达都是Velodyne型号的 xff0c 对于速腾RS雷达的使用者来说 xff0c 需要对数据进行转换 xff0c 其实现在速腾的雷达已经支持输出XYZI和XYZIR
  • LIO-SAM中的mapOptmization

    前言 最近在学习LIO SAM源码的时候 xff0c 发现LIO SAM这套代码调用了比较多库的内置API xff0c 里面涉及的一些细节也比较多 xff0c 整个工程还是比较清晰的 xff0c 值得学习 xff01 LIO SAM这个框架
  • 使用D435i+Avia跑Fast-LIVO

    前言 最近Fast LIVO开源了 xff0c 之前看它的论文的时候发现效果很优秀 xff0c 于是用实验室现有的设备尝试一下 这里主要记录一下使用不带外触发功能的D435i 43 Avia跑Fast LIVO的过程 xff0c 为了适配代
  • CMakeList 中引用系统环境变量中的 include 文件,以及 lib 文件

    CMakeList 中引用系统环境变量中的 include 文件 xff0c 以及 lib 文件 cmake中对环境变量读写都是通过ENV前缀来访问环境变量 ENV ZLIB DIR 表示系统环境变量ZLIB DIR 所表示的路径 以ZLI
  • GroundTrue和里程计输出的位姿的参考坐标系不一致的情况

    这里写目录标题 前言数据集描述使用TF工具包获取使用Eigen库计算置换输出误差对比没做转换之前转换之后 前言 最近遇到一个数据集的ground true参考坐标和vSLAM输出的位姿的参考坐标不一样的问题 xff0c 记录一下 在之前参加
  • Protobuf报错CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):

    前言 Protobuf全称Protocol buffers xff0c 是Google研发的一种跨语言 跨平台的序列化结构的数据格式 xff0c 是一个灵活的 高效的用于序列化数据的协议 使用protobuf时 xff0c 既可以采用动态链