我有一个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
!有没有人建议可能导致这个未定义的符号错误?
答案 0 :(得分:7)
链接库然后尝试加载它时,需要检查一些事项。例如,在Linux中,所有符号只需要在最终加载阶段(加载可执行文件)时可用,对于节点,这将是您运行节点并加载本机插件时。如果缺少符号,则强制节点addon构建失败,必须将-z defs
作为node-gyp中的链接器选项传递。因此,您需要将binding.gyp中的以下内容添加到“link_settings”元素或适当的位置:
"ldflags": [
"-Wl,-z,defs"
]
如果您不知道如何编辑构建和链接,请查看node-gyp教程(类似this)。
注意:似乎节点也推迟了许多内部的符号加载,所以不幸的是,你将获得v8内容的大量未定义符号。这可能是不可避免的,因为节点动态加载这些符号。您必须检查输出并将其传递给寻呼机或grep以查找opencv缺失符号。这个名字在这个阶段不会被破坏。完成后删除这些标志。
如果您在此处获得opencv未定义错误,则表示您正在错误地链接库或根本不链接库。需要注意的一些事项是:
-z defs
; 您可以使用nm查看最终节点插件中定义的符号...预计在最终加载阶段可以使用“U”(未定义)的任何内容。除非您静态链接opencv,否则仍应将opencv符号视为未定义。所以请致电:
$ nm -C myaddon.node
-C将对名称进行解码,如果链接共享库,则应将cv :: Feature2D视为未定义。最后一步是检查加载库时将加载哪些库。使用ldd执行此操作。
$ ldd myaddon.node
这将显示无法找到的任何库。如果未在此处找到opencv库,则表示尚未链接共享库。如果找到库,它还会显示它找到库的位置(您可以使用这些路径确保使用已签出的库)。
只是最终的核选项,opencv似乎有相当多的库,你最好的方法就是将所有这些库连接起来以解决缺失的符号。使用pkgconfig获取所有这些库:
$ pkg-config --libs opencv
您可以使用
获取包含标志$ pkg-config --cflags opencv
将这些东西放在binding.gyp中的适当位置。
答案 1 :(得分:0)
我有一个与此类似的问题,并且我的opencv安装错误(?)。重新安装即可解决问题。
答案 2 :(得分:0)
发现,如果“ #include something.h”中包含某些内容,则编译可以,但是如果我使用(在我的情况下)某些新实例(如“ new Something()”),则将显示“未定义符号”。因此,我应该在“ sources”部分的binding.gyp中包含“ something.cpp”:
"sources": [ "something.cpp" ]