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 コードをテストしたところ動作しましたが、4 番目のパラメーターを追加してリストを取得すると、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)

PyArg_ParseTuple SegFaults in CApiも読みました

pyarg_parsetuple の後に segfault が発生する理由を知っている人はいますか?

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 に答える