C++ python API:第二次调用PyImport_Import结果SIGSEGV
问题描述:
我想通过c Api从C++调用python来获取C++中两个numpy数组的值。 我第一次调用我的程序callPython()似乎一切都在执行C++ python API:第二次调用PyImport_Import结果SIGSEGV
pModule = PyImport_Import(pName);
在SIGSEGV运行正常,但第二个通话效果。
在flebool的答案中,有一个比我的代码简单得多的简单代码,它有相同的错误。
minimal.cpp
#include <Python.h>
#include <numpy/arrayobject.h>
long int geTuple(PyObject *pValue , PyObject *objI , int i)
{
objI = PyTuple_GetItem(pValue, i);
long int n,M;
double *xJ;
if (objI != NULL)
{
n = PyArray_NDIM(objI);
printf("PyArray_NDIM(objI): %ld\n" , n);
M = *PyArray_DIMS(objI);
printf("PyArray_DIMS(objI) : %ld\n" , M);
for (int k = 0; k < M; k++)
{
xJ = (double *) PyArray_GETPTR1(objI, k);
printf("xJ : %f\n" , *xJ);
}
return M;
}
else
{
printf("geTuple is Null \n");
return -1;
}
}
void callPython()
{
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
Py_Initialize();
//Import current folder to Python path
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.insert(0, '')");
// Load name of pythonfile without py
pName = PyString_FromString("minimal");
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL)
{
//Name of the Python function
pFunc = PyObject_GetAttrString(pModule, "minimalFunction");
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc))
{
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, PyInt_FromLong(2));
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL)
{
long int dims[2];
PyObject *ob1,*ob2;
dims[0] = geTuple(pValue , ob1 , 0);
dims[1] = geTuple(pValue , ob2 , 1);
Py_DECREF(pValue);
}
else
{
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return;
}
}
else
{
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", "minimalFunction");
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", "minimal.py");
return ;
}
Py_Finalize();
}
int
main(int argc, char *argv[])
{
callPython();
printf("2nd Call\n");
callPython();
printf("Run over\n");
return 0;
}
minimal.py
#! /usr/bin/env python
import numpy as np
def minimalFunction(dim):
xLower = np.ones(dim)
dCp = np.zeros(dim)
return xLower , dCp
我编译我的程序在Ubuntu 12.04使用Python和numpy的软件包,以及与蟒蛇,用follwing命令:
gcc minimal.cpp -o minimal -I/usr/include/python2.7 -I/usr/include/python2.7 -lpython2.7 -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security
缩短的GDB回溯是
#101 0x00007ffff7a1ebeb in ??() from /usr/lib/libpython2.7.so.1.0
#102 0x00007ffff79e972e in PyObject_CallFunction() from /usr/lib/libpython2.7.so.1.0
#103 0x00007ffff79b312d in PyImport_Import() from /usr/lib/libpython2.7.so.1.0
#104 0x0000000000400cea in callPython() at minimal.cpp:48
#105 0x0000000000400af8 in main (argc=<optimized out>, argv=<optimized out>) at minimal.cpp:110
可能是有什么毛病我的电话到Python?
答
这是一条评论,而不是真正的答案。我不知道你的代码有什么问题。以下(更简单)的例子也失败了。 minimal.cpp
:
#include <Python.h>
void callPython(){
Py_Initialize();
//Import current folder to Python path
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.insert(0, '')");
// Load name of pythonfile without py
PyObject *pName= PyString_FromString("minimal");
/* Error checking of pName left out */
PyObject *pModule= PyImport_Import(pName);
Py_DECREF(pName);
Py_DECREF(pModule);
Py_Finalize();
}
int main(int argc, char *argv[])
{
callPython();
printf("2nd Call\n");
callPython();
printf("Run over\n");
return 0;
}
与此minimal.py
:
import numpy as np
def minimalFunction(dim):
return 1
有趣的是,如果你注释掉import numpy
声明一切工作正常。
我想:
- 没有从外壳任何赛格故障运行
python -m minimal && python -m minimal
,这排除了该问题可能出在numpy
,或者至少它不只是在那里。 - 致电
sleep(2)
拨打电话callPython()
拨打cpp
代码。无论如何它都会发生段错误。
祝你好运!
你说得对,你的版本比我的初始版本简单得多,而且它也失败了。谢谢。 – Arnox 2014-08-28 07:20:50