多个共享对象使用相同的原型导致错误:文件已存在于数据库中

pia*_*oxu 2 c++ protocol-buffers dlopen

与protobuf3相关的错误

我有一个具有c ++可执行核心和几个称为插件的共享库(.so,.dll)的项目。内核启动时,它将使用dlopen加载这些插件。内核和插件使用protobuf作为通信协议,因此它们必须将生成的文件.pb.cc.ph.h文件编译到其二进制文件中,才能获得序列化器/解串器的副本。并libprotobuf.so链接到核心和插件。当我启动核心时,它因错误而崩溃:数据库中已存在文件,#863中存在相同错误

我正在使用protobuf-3 beta2和Ubuntu 14.04。此错误仅在Linux上发生。该程序可以在Windows和OS X上正常运行。

我还尝试了另一种方法,将所有生成的protobuf文件编译成一个动态库(protocol.so),然后将核心和插件链接到protocol.solibprotobuf.so。这很好。当然,因为在#1062中,此错误已得到修复。但是,当我改变了protocol.soprotocol.a,它再次失败。我认为这与.pb.cc单独生成的编译相同。

我不想编译a protocol.so,因为当我添加越来越多的插件时,扩展通信协议对我来说是不便的。我认为将生成.pb.cc的文件编译为插件的二进制文件更好(在Windows和OS X上效果很好)。

任何建议解决此错误表示赞赏。

Ken*_*rda 5

当同一.pb.cc文件的多个已编译副本共享的单个副本时,就会发生此问题libprotobuf.so。有两种方法可以避免这种情况:

  1. 您已经找到的方式:将.pb.cc文件分解到共享库中。
  2. 将libprotobuf的单独副本链接到每个插件中。您需要为此库使用静态链接,即使用libprotobuf.a而不是libprotobuf.so。请注意,使用此选项,在插件和基本应用程序之间传递指向protobuf类的指针是不安全的,因为它们使用的是protobuf库的单独副本,这可能导致崩溃。您将必须将序列化消息传递为字节blob。幸运的是,这就是protobuf的全部重点。

  • @KentonVarda 不仅必须将 `libprotobuf.a` 链接到每个插件中,而且(由于通常的 ELF 符号可见性规则)你必须*隐藏*插件中的所有 `libprotobuf.a` 符号(使用 ` -fvisibility=hidden`,或使用链接器版本脚本)。http://stackoverflow.com/a/37064043/50617 对此进行了更多讨论。 (2认同)