0

我一直在为一个错误而奋斗了很多时间,并且对于发生了什么以及为什么它不起作用,我缺乏想法。在构造函数中获取列表的Python对象扩展从未传递创建步骤(SIGSEV),为什么?

首先,我试图通过C扩展为Python创建一个新的对象类型。这个对象是使用列表,numpy数组等创建的......但我甚至无法使这部分工作。

失败的实际最小码为:

#include <python2.7/Python.h> 
    #include <python2.7/structmember.h> 
    #include <numpy/arrayobject.h> 
    #include "../python/NumpyHelperFuncs.h" 
    #include <cmath> 
    #include <algorithm> 
    #include <iostream> 
    using namespace std; 

    typedef struct { 
     PyObject_HEAD 
    } CondensedMatrix; 

    static void condensedMatrix_dealloc(CondensedMatrix* self){ 
     self->ob_type->tp_free((PyObject*)self); 
    } 

    static PyObject* condensedMatrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds){ 
     CondensedMatrix *self; 
     self = (CondensedMatrix*) type->tp_alloc(type, 0); 
     return (PyObject *) self; 
    } 

    static int condensedMatrix_init(CondensedMatrix *self, PyObject *args, PyObject *kwds){ 
     PyObject* input; 
     PyArrayObject* rmsd_numpy_array; 
     cout<<"Minimum class creation"<<flush<<endl; 

     if (! PyArg_ParseTuple(args, "O",&input)){ 
      PyErr_SetString(PyExc_RuntimeError, "Error parsing parameters."); 
      return -1; 
     } 
     rmsd_numpy_array = (PyArrayObject *) PyArray_ContiguousFromObject(input, PyArray_FLOAT, 1, 1); 
     Py_DECREF(rmsd_numpy_array); 
     return 0; 
    } 

    static PyMemberDef condensedMatrix_members[] = { 
     {NULL} /* Sentinel */ 
    }; 


    static PyMethodDef condensedMatrix_methods[] = { 
     {NULL} /* Sentinel */ 
    }; 

    static PyTypeObject CondensedMatrixType = { 
     PyObject_HEAD_INIT(NULL) 
     0,            /*ob_size*/ 
     "condensedMatrix.CondensedMatrixType",   /*tp_name*/ 
     sizeof(CondensedMatrix), /*tp_basicsize*/ 
     0,       /*tp_itemsize*/ 
     (destructor)condensedMatrix_dealloc, /*tp_dealloc*/ 
     0,       /*tp_print*/ 
     0,       /*tp_getattr*/ 
     0,       /*tp_setattr*/ 
     0,       /*tp_compare*/ 
     0,       /*tp_repr*/ 
     0,       /*tp_as_number*/ 
     0,       /*tp_as_sequence*/ 
     0,       /*tp_as_mapping*/ 
     0,       /*tp_hash */ 
     0,       /*tp_call*/ 
     0,       /*tp_str*/ 
     0,       /*tp_getattro*/ 
     0,       /*tp_setattro*/ 
     0,       /*tp_as_buffer*/ 
     Py_TPFLAGS_DEFAULT| Py_TPFLAGS_BASETYPE ,      /*tp_flags*/ 
     "Condensed matrix as in pdist",   /* tp_doc */ 
     0,      /* tp_traverse */ 
     0,      /* tp_clear */ 
     0,      /* tp_richcompare */ 
     0,      /* tp_weaklistoffset */ 
     0,       /* tp_iter */ 
     0,       /* tp_iternext */ 
     condensedMatrix_methods, /* tp_methods */ 
     condensedMatrix_members, /* tp_members */ 
     0,       /* tp_getset */ 
     0,       /* tp_base */ 
     0,       /* tp_dict */ 
     0,       /* tp_descr_get */ 
     0,       /* tp_descr_set */ 
     0,       /* tp_dictoffset */ 
     (initproc)condensedMatrix_init, /* tp_init */ 
     0,        /* tp_alloc */ 
     condensedMatrix_new,    /* tp_new */ 
    }; 

    #ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ 
    #define PyMODINIT_FUNC void 
    #endif 

    PyMODINIT_FUNC initcondensedMatrix(void){ 
     PyObject* module; 

     if (PyType_Ready(&CondensedMatrixType) < 0) 
      return; 

     module = Py_InitModule3("condensedMatrix", NULL,"Fast Access Condensed Matrix"); 
     if (module == NULL) 
       return; 

     Py_INCREF(&CondensedMatrixType); 
     PyModule_AddObject(module, "CondensedMatrix", (PyObject*) &CondensedMatrixType); 
    } 

此代码已被写入以下的提示(和复制/粘贴):http://docs.python.org/extending/newtypes.html

我测试过诺迪代码和它的作品,但如果我添加第四个参数来获取列表,它也会以sigsev退出。

予编译代码以上:

gcc -pthread -fno-strict-aliasing -fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -fPIC -c matrix.cpp 

g++ -pthread -shared matrix/matrix.o -lpython2.7 -o condensedMatrix.so -fopenmp 

我与使用它: 如果 == '': data_con = [3,4,5,6] 矩阵= CondensedMatrix(data_con)

我也看到PyArg_ParseTuple SegFaults in CApi

有谁知道为什么它在pyarg_parsetuple后执行segfault?

Ubuntu 12.04,gcc 4.6.3,Python 2.7.3

谢谢!

+0

调试器附加到它,并通过它一步? – favoretti 2012-08-08 15:05:59

回答

0

所以,看起来这个错误确实很容易解决,因为唯一需要的是缺少'import_array();'句话在初始化函数:

PyMODINIT_FUNC initcondensedMatrix(void){ 
    PyObject* module; 

    if (PyType_Ready(&CondensedMatrixType) < 0) 
     return; 

    module = Py_InitModule3("condensedMatrix", NULL,"Fast Access Condensed Matrix"); 
    if (module == NULL) 
      return; 

    Py_INCREF(&CondensedMatrixType); 
    PyModule_AddObject(module, "CondensedMatrix", (PyObject*) &CondensedMatrixType); 
    import_array(); 
} 

那全...

相关问题