Raj*_*ani 18 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中加载时会收到带有"未定义符号"消息的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
Run Code Online (Sandbox Code Playgroud)
这是"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
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
ImportError: /path/to/service/mymodule.so: undefined symbol: _ZN5CvSVMD1Ev
Run Code Online (Sandbox Code Playgroud)
我的理解是"未定义的符号"通常意味着在任何链接库中都找不到给定的符号.但是我知道libopencv_ml.so中有这个符号,因为当我运行它时:
$ nm -g /usr/local/lib/libopencv_ml.so | grep _ZN5CvSVMD1Ev
Run Code Online (Sandbox Code Playgroud)
我明白了:
000000000002fd40 T _ZN5CvSVMD1Ev
Run Code Online (Sandbox Code Playgroud)
/ usr/local/lib似乎在动态链接器缓存中.
$ cat /etc/ld.so.conf.d/libc.conf
# libc default configuration
/usr/local/lib
Run Code Online (Sandbox Code Playgroud)
而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
Run Code Online (Sandbox Code Playgroud)
所以你能告诉我我可能做错了什么吗?Ubuntu 11.04和11.10之间在运行Python时加载共享库的方式有什么变化吗?或者这是OpenCV的问题?
Raj*_*ani 20
解决方案是在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
Run Code Online (Sandbox Code Playgroud)
gcc手册页说的是"-l"选项,
它在您编写此选项的命令中有所不同; 链接器按照指定的顺序搜索和处理库和目标文件.因此,foo.o -lz bar.o在文件foo.o之后但在bar.o之前搜索库z.如果bar.o引用z中的函数,则可能无法加载这些函数.
由于mymodule.so的名称是在它应该链接到的库之前提供的,因此它们都没有实际链接到生成的.so文件.
感谢@JFSebastian指出-l如何工作.
| 归档时间: |
|
| 查看次数: |
31212 次 |
| 最近记录: |