使用C ++插件的节点应用程序在运行时抱怨未定义的符号

我有一个NodeJS应用程序,它可以调用一些本地插件来实现一些OpenCV调用。 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 ! 有没有人有什么可能会导致这个未定义的符号错误的build议?

链接库时需要检查一些内容,然后尝试加载它。 例如,在Linux中,所有的符号只需要在最后一个加载阶段(加载可执行文件)就可以得到,而当你运行节点并加载本地插件时,这个节点就是这个节点。 要强制节点插件构build失败,如果有缺less符号,您必须通过-z defs作为node- -z defs中的链接器选项。 所以你可以在binding.gyp中添加以下内容到“link_settings”元素或适当的位置:

 "ldflags": [ "-Wl,-z,defs" ] 

如果您不知道如何编辑构build和链接,请查看node-gyp教程(如下所示 )。

注意 :Node似乎也推迟了很多其内部的符号加载,所以不幸的是,你也会得到很多未定义的符号。 由于节点dynamic加载这些符号,这可能是不可避免的。 您将不得不检查输出,并将其传送到寻呼机或grep,以查找缺less符号的opencv。 在这个阶段,名字不会被破坏。 当你完成删除这些标志。

如果你在这里得到opencv未定义的错误,这意味着你正在错误地链接库或者根本没有链接。 有些事情要注意的是:

  • 如果你在“libraries”元素的某个地方拥有了所有的-lopencv_ *库链接标志,如果你不是,那么你实际上并没有链接opencv,但是如果没有-z defs ,通常就不会抱怨;
  • 如果它正在链接与您正在使用的标题相对应的库(避免这些问题最简单的方法就是使用您的发行版的opencv)。 如果您需要在binding.gyp中使用checkc版本的opencv,可以通过设置include和librarysearchpath的构build标志来明确这些事情。

您可以使用nm来查看您的最终节点插件中定义了哪些符号…任何带有“U”(未定义)的东西都预计在最后的加载阶段可用。 除非静态链接opencv,否则您仍然应该将opencv符号视为undefined。 所以打电话:

 $ nm -C myaddon.node 

-C会将名称解体,如果链接了共享库,则应该看到cv :: Feature2D为undefined。 最后一步是检查你的库加载时会加载哪些库。 使用ldd来做到这一点。

 $ ldd myaddon.node 

这将显示任何找不到的库。 如果在这里没有findopencv库,你还没有链接共享库。 它也会告诉你它find它们的地方(你可以使用这些path来确保你正在使用你的签出库)。

只是最后的核选项,opencv似乎有好几个库,你最好的办法就是把它们全部链接起来解决缺失的符号。 使用pkgconfig获取所有这些库:

 $ pkg-config --libs opencv 

你可以得到包含标志

 $ pkg-config --cflags opencv 

把这些东西放在你的binding.gyp的相应位置。