Python ImportError-未定义的符号-用于自定义C++模块
Python ImportError - undefined symbol - for custom C++ module
我一直在Ubuntu 11.04上使用OpenCV 2.3到2.4.2开发C++中的Python模块。OpenCV是从源代码构建的。我没有使用Ubuntu存储库中的OpenCV版本。
我的Python模块编译时没有出现任何问题,并且在Python中正确加载。然而,当我在Ubuntu 11.10或12.04上编译这个模块时,当我试图在Python中加载它时,我会收到一个ImportError,其中包含消息"undefined symbol"。
这就是我编译模块的方式:
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
我的理解是,"未定义符号"通常意味着在任何链接库中都找不到给定的符号。但我知道这个符号在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
你能告诉我我可能做错了什么吗?在Ubuntu 11.04和11.10之间,运行Python时加载共享库的方式是否发生了变化?或者这是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
选项
在命令中写入此选项的位置会有所不同;这个链接器按顺序搜索和处理库和对象文件它们被指定。因此,
foo.o -lz bar.o
在文件foo.o,但在bar.o之前。如果bar.o引用z中的函数,则可能无法加载函数。
由于mymodule.so的名称是在它应该链接到的库之前提供的,因此它们实际上都没有链接到生成的.so文件。
感谢@J.F.Sebastian指出-l
的工作原理。
- std::ranges::elements_view,用于自定义类似元组的数据
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- SetCurrentConsoleFontEx() 不适用于自定义安装的字体
- 自定义 STL 兼容迭代器,用于迭代 2D 数组类的列
- '_HAS_CXX17'宏是否可用于自定义项目标头以启用C++17 语言集功能?
- 如何将 AST 用于自定义前端操作和 clang 静态分析
- c++ 中的自定义分配器,用于不调用secure_string实现
- 用于自定义调试构建的 CMake qt 输入库后缀
- 用于自定义间距的 .clang 格式选项
- 为什么我的代码不适用于自定义分配器?
- Python ImportError-未定义的符号-用于自定义C++模块
- 运算符 -> 不适用于自定义输入迭代器
- 继承自 std::vector<T> 和重载运算符 [] 用于自定义索引
- 带堆的贝尔曼-福特不适用于自定义比较函数
- BOOST_CHECK无法编译运算符<<用于自定义类型
- 用于自定义类型的自定义c++流
- Push_back()不适用于自定义数据类型(模板类)
- 如何将std::find/std::find_if用于自定义类对象的向量
- 无序集-如何将C++无序集用于自定义类
- 操作符的算法重载-用于自定义整数类