在C语言中嵌入Python – Segfault
从阅读另一篇文章 ,我试图在C中嵌入一些Python代码:
main.c中
#include int callModuleFunc(int array[], size_t size) { PyObject *mymodule = PyImport_ImportModule("py_function"); PyObject *myfunc = PyObject_GetAttrString(mymodule, "printlist"); PyObject *mylist = PyList_New(size); for (size_t i = 0; i != size; ++i) { PyList_SET_ITEM(mylist, i, PyInt_FromLong(array[i])); } PyObject *arglist = Py_BuildValue("(o)", mylist); PyObject *result = PyObject_CallObject(myfunc, arglist); int retval = (int)PyInt_AsLong(result); Py_DECREF(result); Py_DECREF(arglist); Py_DECREF(mylist); Py_DECREF(myfunc); Py_DECREF(mymodule); return retval; } int main(int argc, char *argv[]) { int a[] = {1,2,3,4}; callModuleFunc(a, 4); return 0; }
py_function.py
'''py_function.py - Python source designed to ''' '''demonstrate the use of python embedding''' def printlist(mylist): print mylist
然后我编译:
gcc main.c -I/usr/include/python2.7 -lpython2.7
但后来我运行了应用程序,它给了我一个分段错误错误:
/a.out [1] 18890 segmentation fault ./a.out
有什么东西我不见了吗?
你的代码有几个问题:
- 没有调用
Py_Initialize()
。 -
PyImport_ImportModule()
无法找到你的python文件,因为在嵌入式Python中你没有初始模块,相对于搜索可以工作。 修复是在sys.path
显式包含当前目录。 -
Py_BuildValue()
"(O)"
应使用大写Py_BuildValue()
'O'
。 -
printlist
函数应返回一个值(因为这是C代码所期望的)。
这应该工作:
main.c中
#include void initPython() { Py_Initialize(); PyObject *sysmodule = PyImport_ImportModule("sys"); PyObject *syspath = PyObject_GetAttrString(sysmodule, "path"); PyList_Append(syspath, PyString_FromString(".")); Py_DECREF(syspath); Py_DECREF(sysmodule); } int callModuleFunc(int array[], size_t size) { PyObject *mymodule = PyImport_ImportModule("py_function"); assert(mymodule != NULL); PyObject *myfunc = PyObject_GetAttrString(mymodule, "printlist"); assert(myfunc != NULL); PyObject *mylist = PyList_New(size); for (size_t i = 0; i != size; ++i) { PyList_SET_ITEM(mylist, i, PyInt_FromLong(array[i])); } PyObject *arglist = Py_BuildValue("(O)", mylist); assert(arglist != NULL); PyObject *result = PyObject_CallObject(myfunc, arglist); assert(result != NULL); int retval = (int)PyInt_AsLong(result); Py_DECREF(result); Py_DECREF(arglist); Py_DECREF(mylist); Py_DECREF(myfunc); Py_DECREF(mymodule); return retval; } int main(int argc, char *argv[]) { initPython(); int a[] = {1,2,3,4,5,6,7}; callModuleFunc(a, 4); callModuleFunc(a+2, 5); Py_Finalize(); return 0; }
py_function.py
'''py_function.py - Python source designed to ''' '''demonstrate the use of python embedding''' def printlist(mylist): print mylist return 0