c++ - 带有 C++ 插件的 Node 应用程序在运行时提示 undefined symbol

标签 c++ node.js opencv node-gyp

我有一个 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/

相关文章:

python - 如何使用 OpenCV 绘图函数绘制填充矩形?

c++ - ReadFile 使用 NamedPipe block 虽然使用重叠

node.js - 如何在 typescript 中引用@types/module?

javascript - 抓取一组包含混合内容的页面的最佳方法

opencv - 如何在低通滤波图像上找到轮廓?

C++/OpenCV 在图像上查找对象

c++ - QVector、QList 等。为什么索引是 int 而不是 size_t

c++ - 如何不画出场景边界?

C++,非常意外-1#INF

node.js - 如何在生产中运行 `prisma generate`?