Python ImportError - символ undefined - для пользовательского модуля С++ - программирование
Подтвердить что ты не робот

Python ImportError - символ undefined - для пользовательского модуля С++

Я разрабатываю модуль Python на С++ с использованием OpenCV с 2.3 по 2.4.2 на Ubuntu 11.04. OpenCV был построен из источника. Я не использую версию OpenCV из репозиториев Ubuntu.

Модуль My Python компилируется без проблем и правильно загружается в Python. Однако, когда я компилирую этот модуль на Ubuntu 11.10 или 12.04, я получаю ImportError с сообщением "undefined symbol" при попытке загрузить его в Python.

Вот как я скомпилирую модуль:

g++ -fPIC -shared `pkg-config --cflags --libs python` `pkg-config --cflags --libs opencv` -I/usr/local/include/opencv2/legacy -o mymodule.so mymodule.cpp

Это вывод "pkg-config -cflags -libs opencv"

-I/usr/local/include/opencv -I/usr/local/include  /usr/local/lib/libopencv_calib3d.so /usr/local/lib/libopencv_contrib.so /usr/local/lib/libopencv_core.so /usr/local/lib/libopencv_features2d.so /usr/local/lib/libopencv_flann.so /usr/local/lib/libopencv_gpu.so /usr/local/lib/libopencv_highgui.so /usr/local/lib/libopencv_imgproc.so /usr/local/lib/libopencv_legacy.so /usr/local/lib/libopencv_ml.so /usr/local/lib/libopencv_nonfree.so /usr/local/lib/libopencv_objdetect.so /usr/local/lib/libopencv_photo.so /usr/local/lib/libopencv_stitching.so /usr/local/lib/libopencv_ts.so /usr/local/lib/libopencv_video.so /usr/local/lib/libopencv_videostab.so

Ошибка, которую я получаю:

ImportError: /path/to/service/mymodule.so: undefined symbol: _ZN5CvSVMD1Ev

Я понимаю, что "undefined symbol" обычно означает, что данный символ не может быть найден ни в одной из связанных библиотек. Но я знаю, что этот символ есть в libopencv_ml.so, потому что когда я запускаю это:

$ nm -g  /usr/local/lib/libopencv_ml.so | grep _ZN5CvSVMD1Ev

Я получаю:

000000000002fd40 T _ZN5CvSVMD1Ev

/usr/local/lib, похоже, находится в динамическом кэше компоновщика.

$ cat /etc/ld.so.conf.d/libc.conf 
# libc default configuration
/usr/local/lib

И такой файл также находится в кеше.

$ ldconfig -p | grep opencv | grep ml
        libopencv_ml.so.2.4 (libc6,x86-64) => /usr/local/lib/libopencv_ml.so.2.4
        libopencv_ml.so (libc6,x86-64) => /usr/local/lib/libopencv_ml.so

Итак, можете ли вы дать мне понять, что я могу делать неправильно? Что-то изменилось между Ubuntu 11.04 и 11.10 в том, как загружаются общие библиотеки при запуске Python? Или это проблема с OpenCV?

4b9b3361

Ответ 1

Решение состоит в том, чтобы сгенерировать имя сгенерированного модуля перед другими его модулями, в командной строке g++.

g++ -fPIC -shared -o mymodule.so mymodule.cpp `pkg-config --cflags --libs python` `pkg-config --cflags --libs opencv` -I/usr/local/include/opencv2/legacy

В man-странице gcc говорится о опции "-l",

Это имеет значение, когда в команде вы пишете эту опцию; компоновщик ищет и обрабатывает библиотеки и объектные файлы в порядке они указаны. Таким образом, foo.o -lz bar.o выполняет поиск библиотеки z после файл foo.o, но до bar.o. Если bar.o относится к функциям из z, то функции не могут быть загружены.

Поскольку имя mymodule.so было предоставлено перед библиотеками, к которым он должен был быть связан, ни один из них не был фактически связан с сгенерированным файлом .so.

Спасибо за @J.F.Sebastian за указание, как работает -l.