我在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 | …Run Code Online (Sandbox Code Playgroud) 我目前遇到一个问题,我可以numpy在解释器环境中使用和导入,但我无法导入或使用numpy嵌入的python C/C++.所以我很好奇如何numpy扩展库
numpy/core/multiarray.cpython-35m-x86_64-linux-gnu.so
Run Code Online (Sandbox Code Playgroud)
链接到标准的python包符号(PyExc_UserWarning具体为符号).我当前的错误输出说明了PyExc_UserWarning is undefined.libpythonX.Y.m.so当我使用nm命令确认时,此符号存在.我跑了
ldd multiarray.cpython-35m-x86_64-linux-gnu.so
Run Code Online (Sandbox Code Playgroud)
得到以下输出:
在我看来,这个库没有链接到应该包含该符号的任何动态库.怎样numpy的multiarray.cpython-35m-x86_64-linux-gnu.so通常会发现,符号或者多阵列的变化发现,象征?
感谢您抽出宝贵的时间阅读这个问题.任何想法,建议或答案都表示赞赏!
原来的问题就在这里.这是原始问题的一个子问题.我之所以提出这个问题是因为我怀疑这个共享库可能链接到了错误的位置,而这个特定的共享库只在通过python C/C++接口调用python时使用.
系统规格+问题信息
pip3.5 install numpy命令使用pip 9.0.0安装numpy-1.14.2修改了一些不清楚的术语.
我找到了原始问题的答案; 然而,这个问题和原始问题仍然是开放的,因为这个问题的答案可以为原始问题找到更好的答案.
我正在尝试用C语言编写一个演示PAM模块,该模块使用在C概念中嵌入Python来运行以python(2.7)编写的脚本,该脚本位于pam_sm_authenticate()函数内部,该函数以C文件(pam_auth.c)编写。
这是python脚本:test.py
import math
import numpy
def test_func():
a = "test"
return a
Run Code Online (Sandbox Code Playgroud)
test.py的路径是/usr/lib/Python2.7/,以便我可以轻松导入它。
这是C文件:
#define PAM_SM_AUTH
#define PAM_SM_ACCOUNT
#define PAM_SM_SESSION
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
#include <security/pam_appl.h>
#include<python2.7/Python.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define NOBODY "nobody"
/*PAM Stuffs*/
PAM_EXTERN int pam_sm_authenticate(
pam_handle_t* pamh, int flags, int argc, const char** argv)
{
const char *user;
int retval;
user = NULL;
retval = pam_get_user(pamh, &user, NULL);
if(retval != PAM_SUCCESS)
{
fprintf(stderr, "%s", pam_strerror(pamh, retval));
// return (retval);
}
fprintf(stdout, "retval= %d user=%s\n", retval,user);
if …Run Code Online (Sandbox Code Playgroud)