Protobuf 和 Node.JS 库错误

Posted

技术标签:

【中文标题】Protobuf 和 Node.JS 库错误【英文标题】:Protobuf and Node.JS library error 【发布时间】:2016-02-06 20:51:42 【问题描述】:

我正在 Ubuntu 14.04 LTS 上使用带有 Node.JS 的 google 协议缓冲区。我有两个使用相同协议缓冲区和 protobuf 库的不同(A 和 B)Node.JS 插件(c++)。当我在之前需要模块 A 之后使用 require() 创建模块 B 的新实例时,服务器停止并显示错误消息:

[libprotobuf ERROR google/protobuf/descriptor_database.cc:57] File already exists in database: Anam.proto 
[libprotobuf FATAL google/protobuf/descriptor.cc:1157] 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)

我用谷歌搜索了这个错误,发现其他人只在 Linux 上遇到这个错误。我还从 github 安装了最新版本的 protobuf 库,但没有帮助。我包含 libprotobuf 的 binding.gyp 部分如下所示:

"libraries": ["/usr/lib/libpq.so",
              "/usr/local/lib/libprotobuf.so",
              "/usr/local/lib/libboost_system.so",
              "/usr/local/lib/libboost_thread.so",
              "/usr/local/lib/libboost_signals.so"]

如果我为同一个模块创建更多实例(例如需要插件 A 2 次),它就可以工作。有人对如何解决这个问题有任何建议吗?

【问题讨论】:

【参考方案1】:

问题可能是这两个 C++ 模块都包含相同 .proto 文件的单独编译副本,但共享 libprotobuf.so 的相同副本。每个都尝试向全局类型描述符表注册其 protobuf 描述符类型,然后看到冲突。

有两种方法可以解决问题:

    将共享的 .proto 文件移动到两个模块链接的共享库中(这样它们最终会共享一份已编译的原型)。 使每个模块静态链接到 libprotobuf,以便它们共享 libprotobuf。这样每个人都会得到自己的描述符表。请注意,如果一个模块曾经接收到另一个模块创建的 protobuf 对象,则这种方法将不起作用(如果它们只交换序列化消息,而不是对象,那很好)。

请注意,此问题会影响所有平台,但人们可能在 Windows 上看不到它,因为静态链接 libprotobuf 在那里更为常见。

【讨论】:

感谢您的回答!针对 libprotobuf 的静态链接解决了这个问题(我链接 .a 文件而不是 .so 文件,如下所示:“libraries”:[“/usr/local/lib/libprotobuf.a”,...])。我总是与序列化消息进行通信,所以它工作得很好。

以上是关于Protobuf 和 Node.JS 库错误的主要内容,如果未能解决你的问题,请参考以下文章

WCF use ProtoBuf

在便携式库上安装 protobuf-net 时出现 nuget 错误

Node.js 异步库比较 - Q 与 Async

如何将第三方 JavaScript 库添加到 Meteor 应用程序?

Node.js 错误:找不到模块快递

如何包含适用于 Node.js 的 Amazon EC2 库?