0

我一直在与一个错误作斗争,但我对正在发生的事情以及为什么它不起作用没有任何想法。

首先,我试图通过 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

我已经测试了 Noddy 代码并且它可以工作,但是如果我添加第四个参数来获取列表,它也会以 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

我使用它: if name == ' main ': data_con = [3,4,5,6] matrix = CondensedMatrix(data_con)

我还阅读了 CApi 中的 PyArg_ParseTuple SegFaults

有谁知道为什么在 pyarg_parsetuple 之后会出现段错误?

Ubuntu 12.04、gcc 4.6.3、Python 2.7.3

谢谢!

4

1 回答 1

0

因此,看起来该错误确实很容易解决,因为唯一需要的是缺少“import_array();” init函数中的语句:

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();
}

仅此而已...

于 2012-08-15T13:53:44.537 回答