我一直在与一个错误作斗争,但我对正在发生的事情以及为什么它不起作用没有任何想法。
首先,我试图通过 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
谢谢!