c++ - Python ImportError - undefined symbol - 用于自定义 C++ 模块

标签 c++ python opencv shared-libraries

我一直在 Ubuntu 11.04 上使用 OpenCV 2.3 到 2.4.2 开发 C++ 中的 Python 模块。 OpenCV 是从源代码构建的。我没有使用 Ubuntu 存储库中的 OpenCV 版本。

我的 Python 模块编译没有问题,并且在 Python 中正确加载。但是,当我在 Ubuntu 11.10 或 12.04 上编译此模块时,尝试在 Python 中加载它时会收到带有消息“ undefined symbol ”的 ImportError。

这是我编译模块的方式:

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

so 文件也在缓存中。

$ 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

那么你能告诉我我可能做错了什么吗?在运行 Python 时加载共享库的方式在 Ubuntu 11.04 和 11.10 之间是否发生了变化?或者这是 OpenCV 的问题?

最佳答案

解决方案是在 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

gcc 手册页提到了 -l 选项,

It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

由于 mymodule.so 的名称是在它应该链接到的库之前提供的,因此它们实际上都没有链接到生成的 .so 文件。

感谢@J.F.Sebastian 指出 -l 的工作原理。

关于c++ - Python ImportError - undefined symbol - 用于自定义 C++ 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11643666/

相关文章:

c++ - 警告#411 : class foo defines no constructor to initialize the following:

python - 正则表达式忽略数字后跟单词/非数字字符

python - 关于 numpy 关联 : not giving expected result 的问题

python - OpenCV 未在图像上添加线和点

Python 检索 JPEG 图像上黑色矩形左上角的 (x,y) 坐标

c++ - boolean 复合赋值中的隐式转换?

c++ - 混合代码 - 函数成员指针

python 子进程调用 bash 脚本 - 也需要打印引号

python - opencv_creatsamples 错误 : free() :corrupted unsorted chunks:

c++ - 设置 ITEMWriter 写入 4K 视频