2016-05-01 1 views
1

У меня есть приложение NodeJS, которое вызывает некоторые вызовы в собственный аддон, который реализует некоторые вызовы OpenCV. Команда node-gyp build успешно, но каждый раз, когда я пытаюсь запустить сервер с node app я получаю:Узел приложения с аддоном C++ жалуется на неопределенный символ во время выполнения

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 явно в любом коде! Кто-нибудь имеет предложение о том, что может вызвать эту неопределенную ошибку?

ответ

5

Есть несколько вещей, которые нужно проверить при связывании библиотеки, а затем в попытке загрузить ее. В Linux, например, все символы должны быть доступны только на этапе окончательной загрузки (загрузка исполняемого файла), с узлом это будет при запуске узла и загрузке собственного аддона. Чтобы заставить сборку аддонов узла сбой, если отсутствуют символы, вы должны передать -z defs в качестве опции компоновщика в node-gyp. Таким образом, вы бы добавить следующее в вашем binding.gyp к элементу «link_settings» или, где это необходимо:

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

Пожалуйста, посмотрите на узел-Gyp учебник (что-то вроде this), если вы не знаете, как изменить строительства и связи.

примечание: Похоже, что узел также блокирует загрузку символа большого количества его внутренних элементов, поэтому, к сожалению, вы также получите множество неопределенных символов для вещей v8. Вероятно, это неизбежно, поскольку узел динамически загружает эти символы. Вам нужно будет проверить выход и передать его на пейджер или grep, чтобы найти отсутствующие символы opencv. На этом этапе имена не будут искалечены. Когда вы закончите, удалите эти флаги.

Если вы обнаружили ошибки undefined opencv, это означает, что вы неправильно или неправильно связываете библиотеку. Некоторые вещи, которые нужно посмотреть являются:

  • , если у вас есть все -lopencv_ * библиотека ссылок флаги в элементе «библиотеки» где-то, если вы не делаете вы на самом деле не связывая OpenCV, но это обычно не жалуются без -z defs;
  • , если он связывает библиотеку, которая соответствует используемым вами заголовкам (самый простой способ избежать подобных проблем - просто использовать opencv вашего дистрибутива). Вы можете быть явным об этих вещах, если вам нужно использовать проверенную версию opencv в вашем bind.gyp, установив флаги сборки для путей включения и поиска библиотек.

Вы можете использовать nm, чтобы посмотреть, какие символы определены в вашем последнем узле узла ... ожидается, что на этапе окончательной загрузки будет доступно что-либо с «U» (неопределенным). Вы все равно должны видеть символы opencv как undefined, если вы не статически связаны с opencv. Так называют:

$ nm -C myaddon.node 

Параметр -C будет demangle имена, вы должны увидеть резюме :: Feature2D как неопределенные, если вы связаны общей библиотеки. Последний шаг - проверить, какие библиотеки будут загружаться при загрузке вашей библиотеки. Используйте ldd для этого.

$ ldd myaddon.node 

Это покажет вам любые библиотеки, которые не были найдены. Если библиотеки opencv не найдены здесь, вы не связали общую библиотеку. Он также покажет вам, где он находит библиотеки, если он их найдет (вы можете использовать эти пути, чтобы убедиться, что используете свои проверенные библиотеки).

Просто окончательный ядерный вариант, opencv имеет довольно много библиотек, кажется, лучше всего связать все их, чтобы разрешить отсутствующие символы. Получить всю эту LIBS с pkg-config:

$ pkg-config --libs opencv 

Вы можете получить включают флаги с

$ pkg-config --cflags opencv 

Положите вещи в соответствующих местах в вашем binding.gyp.

+1

Спасибо за комментарий! Я решил найти проблему. Я думал, что я связываюсь с OpenCV 3.0, который был установлен в/opt/opencv, но он случайно связывался с OpenCv 2.4 в/usr/local из-за порядка путей в путях поиска include. Взял меня навсегда, чтобы понять это. –