我有一个 NodeJS 应用程序,它对实现了一些 OpenCV 调用的 native 插件进行了一些调用。 node-gyp build
命令成功,但每次我尝试使用 node app
运行服务器时,我得到:
Error: /home/cmaccess/SfMLocalization/VisionLocalizeServer/build/Release/localizeImage.node: undefined symbol: _ZNK2cv9Feature2D5emptyEv
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at bindings (/home/cmaccess/SfMLocalization/VisionLocalizeServer/node_modules/bindings/bindings.js:76:44)
at Object.<anonymous> (/home/cmaccess/SfMLocalization/VisionLocalizeServer/routes/localize.js:28:37)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
我这辈子都弄不明白为什么会这样。我检查了一个已知的良好修订并重新安装了 OpenCV。我什至没有在任何代码中明确使用 cv::Feature2D
!有没有人对可能导致此 undefined symbol 错误的原因有任何建议?
最佳答案
在链接一个库然后尝试加载它时,有几件事需要检查。例如,在 Linux 中,所有符号只需要在最终加载阶段(加载可执行文件)可用,对于 Node ,这将在您运行 Node 并加载 native 插件时可用。如果缺少符号,要强制 Node 插件构建失败,您必须将 -z defs
作为 node-gyp 中的链接器选项传递。因此,您可以在 binding.gyp 中将以下内容添加到“link_settings”元素或适当的地方:
"ldflags": [
"-Wl,-z,defs"
]
如果您不知道如何编辑构建和链接,请查看 node-gyp 教程(类似于 this)。
注意: Node 似乎也延迟了其内部的许多符号加载,因此不幸的是,您也会为 v8 内容获得大量 undefined symbol 。这可能是不可避免的,因为 Node 会动态加载这些符号。您将必须检查输出并将其通过管道传输到寻呼机或 grep 以查找 opencv 丢失的符号。名称不会在这个阶段被破坏。完成后删除这些标志。
如果您在此处遇到 opencv 未定义错误,则意味着您链接库不正确或根本没有链接。需要注意的一些事项是:
- 如果你在某处的“库”元素中有所有 -lopencv_* 库链接标志,如果你不这样做,你实际上并没有链接 opencv,但如果没有
-z defs
它通常不会提示; - 如果它正在链接与您正在使用的 header 相对应的库(避免此类问题的最简单方法就是使用您的发行版的 opencv)。如果您需要在 binding.gyp 中使用已 checkout 的 opencv 版本,您可以明确说明这些事情,方法是为包含和库搜索路径设置构建标志。
您可以使用 nm 来查看在您的最终 Node 插件中定义了哪些符号......任何带有“U”(未定义)的东西都应该在最终加载阶段可用。除非静态链接 opencv,否则您仍应看到 opencv 符号为未定义。所以调用:
$ nm -C myaddon.node
-C 将分解名称,如果您链接共享库,您应该看到 cv::Feature2D 未定义。最后一步是检查加载库时将加载哪些库。使用 ldd 来执行此操作。
$ ldd myaddon.node
这将向您显示所有找不到的库。如果在这里找不到 opencv 库,则说明您没有链接共享库。如果确实找到了这些库,它还会向您显示它在哪里找到这些库(您可以使用这些路径来确保您使用的是 checkout 的库)。
只是最后一个核选项,opencv 似乎有很多库,最好的办法是将它们全部链接起来以解决丢失的符号。使用 pkgconfig 获取所有这些库:
$ pkg-config --libs opencv
您可以使用
获取包含标志$ pkg-config --cflags opencv
将这些东西放在 binding.gyp 中的适当位置。
关于c++ - 带有 C++ 插件的 Node 应用程序在运行时提示 undefined symbol ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36961635/