在C语言中嵌入Python - Segfault

时间:2016-06-07 19:30:06

标签: python c segmentation-fault

从另一个post开始,我试图将一些Python代码嵌入到C:

的main.c

#include <Python.h>

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

我有什么遗失的东西吗?

1 个答案:

答案 0 :(得分:4)

您的代码存在一些问题:

  1. Py_Initialize()未被调用。
  2. PyImport_ImportModule()找不到您的python文件,因为在嵌入式Python中,您启动而不是一个初始模块,相对于该模块,搜索可以起作用。修复方法是在sys.path
  3. 中明确包含当前目录 "(O)"中的
  4. Py_BuildValue()应使用大写'O'
  5. printlist函数应返回一个值(因为这是C代码所期望的)。
  6. 这应该有效:

    <强>的main.c

    #include <Python.h>
    
    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