已创建新 python 类型但 PyGetSetDef 核心转储
New python type created but PyGetSetDef core dumps
我有以下代码尝试创建新类型并使用 getter 方法访问值。
#include <Python.h>
#include <structmember.h>
struct rangerr {
long min;
long max;
};
//Python type to represent rangerr
struct py_rangerr {
PyObject_HEAD
struct rangerr range;
};
// * get & set methods for py_rangerr
static PyObject * py_rangerr_min_get(struct py_rangerr *self) {
self->range.min = 1;
return PyLong_FromLong(self->range.min);
}
static PyObject * py_rangerr_max_get(struct py_rangerr *self) {
self->range.max = 10;
return PyLong_FromLong(self->range.max);
}
//* GetSet method definition for py_rangerr
static PyGetSetDef py_rangerr_getset[] = {
{"min",(getter)py_rangerr_min_get, NULL, "min",NULL},
{"max",(getter)py_rangerr_max_get, NULL, "max",NULL},
/* Sentinel */
{NULL},
};
/******************************************************************************
*/
static void py_rangerr_dealloc(struct py_rangerr *self) {
self->ob_type->tp_free((PyObject *)self);
}
static PyTypeObject py_rangerr_type = {
PyObject_HEAD_INIT(NULL)
.tp_basicsize = sizeof(struct py_rangerr),
.tp_dealloc = (destructor) py_rangerr_dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_alloc = PyType_GenericAlloc,
.tp_doc = "rangerr",
.tp_getset = py_rangerr_getset,
};
void
initrangerr(void)
{
PyObject* mod;
mod = Py_InitModule3("rangerr", NULL, "An extension with a type.");
if (mod == NULL) {
return;
}
py_rangerr_type.tp_new = PyType_GenericNew;
if (PyType_Ready(&py_rangerr_type) < 0){
return;
}
Py_INCREF(&py_rangerr_type);
PyModule_AddObject(mod, "rangerr", (PyObject*)&py_rangerr_type);
}
我可以导入新类型
import rangerr as r1
但访问获取方法崩溃
print r1.rangerr.min
编辑:
(gdb) bt
#0 0x0000003a93331890 in __strrchr_sse42 () from /lib64/libc.so.6
#1 0x0000003a9c29b72b in ?? () from /lib64/libpython2.7.so.1.0
#2 0x0000003a9c29b922 in ?? () from /lib64/libpython2.7.so.1.0
#3 0x0000003a9c282d7a in _PyObject_Str () from /lib64/libpython2.7.so.1.0
#4 0x0000003a9c282e4a in PyObject_Str () from /lib64/libpython2.7.so.1.0
#5 0x0000003a9c282ff5 in ?? () from /lib64/libpython2.7.so.1.0
#6 0x0000003a9c266a88 in PyFile_WriteObject () from /lib64/libpython2.7.so.1.0
#7 0x0000003a9c2db09d in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#8 0x0000003a9c2ddcbf in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#9 0x0000003a9c2ddd92 in PyEval_EvalCode () from /lib64/libpython2.7.so.1.0
#10 0x0000003a9c2f6f7a in ?? () from /lib64/libpython2.7.so.1.0
#11 0x0000003a9c2f8c04 in PyRun_InteractiveOneFlags () from /lib64/libpython2.7.so.1.0
#12 0x0000003a9c2f8dde in PyRun_InteractiveLoopFlags () from /lib64/libpython2.7.so.1.0
#13 0x0000003a9c2f937c in PyRun_AnyFileExFlags () from /lib64/libpython2.7.so.1.0
#14 0x0000003a9c309c52 in Py_Main () from /lib64/libpython2.7.so.1.0
#15 0x0000003a93221a05 in __libc_start_main () from /lib64/libc.so.6
#16 0x0000000000400721 in _start ()
(gdb)
您需要定义tp_name
。目前这个字段根本没有设置。
static PyTypeObject py_rangerr_type = {
[...]
.tp_name = "rangerr.rangerr",
[...]
};
您在此处获取核心转储,因为Python 试图显示类型的名称:
>>> print r1.rangerr.min
<attribute 'min' of 'rangerr.rangerr' objects>
我有以下代码尝试创建新类型并使用 getter 方法访问值。
#include <Python.h>
#include <structmember.h>
struct rangerr {
long min;
long max;
};
//Python type to represent rangerr
struct py_rangerr {
PyObject_HEAD
struct rangerr range;
};
// * get & set methods for py_rangerr
static PyObject * py_rangerr_min_get(struct py_rangerr *self) {
self->range.min = 1;
return PyLong_FromLong(self->range.min);
}
static PyObject * py_rangerr_max_get(struct py_rangerr *self) {
self->range.max = 10;
return PyLong_FromLong(self->range.max);
}
//* GetSet method definition for py_rangerr
static PyGetSetDef py_rangerr_getset[] = {
{"min",(getter)py_rangerr_min_get, NULL, "min",NULL},
{"max",(getter)py_rangerr_max_get, NULL, "max",NULL},
/* Sentinel */
{NULL},
};
/******************************************************************************
*/
static void py_rangerr_dealloc(struct py_rangerr *self) {
self->ob_type->tp_free((PyObject *)self);
}
static PyTypeObject py_rangerr_type = {
PyObject_HEAD_INIT(NULL)
.tp_basicsize = sizeof(struct py_rangerr),
.tp_dealloc = (destructor) py_rangerr_dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_alloc = PyType_GenericAlloc,
.tp_doc = "rangerr",
.tp_getset = py_rangerr_getset,
};
void
initrangerr(void)
{
PyObject* mod;
mod = Py_InitModule3("rangerr", NULL, "An extension with a type.");
if (mod == NULL) {
return;
}
py_rangerr_type.tp_new = PyType_GenericNew;
if (PyType_Ready(&py_rangerr_type) < 0){
return;
}
Py_INCREF(&py_rangerr_type);
PyModule_AddObject(mod, "rangerr", (PyObject*)&py_rangerr_type);
}
我可以导入新类型
import rangerr as r1
但访问获取方法崩溃
print r1.rangerr.min
编辑:
(gdb) bt
#0 0x0000003a93331890 in __strrchr_sse42 () from /lib64/libc.so.6
#1 0x0000003a9c29b72b in ?? () from /lib64/libpython2.7.so.1.0
#2 0x0000003a9c29b922 in ?? () from /lib64/libpython2.7.so.1.0
#3 0x0000003a9c282d7a in _PyObject_Str () from /lib64/libpython2.7.so.1.0
#4 0x0000003a9c282e4a in PyObject_Str () from /lib64/libpython2.7.so.1.0
#5 0x0000003a9c282ff5 in ?? () from /lib64/libpython2.7.so.1.0
#6 0x0000003a9c266a88 in PyFile_WriteObject () from /lib64/libpython2.7.so.1.0
#7 0x0000003a9c2db09d in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#8 0x0000003a9c2ddcbf in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#9 0x0000003a9c2ddd92 in PyEval_EvalCode () from /lib64/libpython2.7.so.1.0
#10 0x0000003a9c2f6f7a in ?? () from /lib64/libpython2.7.so.1.0
#11 0x0000003a9c2f8c04 in PyRun_InteractiveOneFlags () from /lib64/libpython2.7.so.1.0
#12 0x0000003a9c2f8dde in PyRun_InteractiveLoopFlags () from /lib64/libpython2.7.so.1.0
#13 0x0000003a9c2f937c in PyRun_AnyFileExFlags () from /lib64/libpython2.7.so.1.0
#14 0x0000003a9c309c52 in Py_Main () from /lib64/libpython2.7.so.1.0
#15 0x0000003a93221a05 in __libc_start_main () from /lib64/libc.so.6
#16 0x0000000000400721 in _start ()
(gdb)
您需要定义tp_name
。目前这个字段根本没有设置。
static PyTypeObject py_rangerr_type = {
[...]
.tp_name = "rangerr.rangerr",
[...]
};
您在此处获取核心转储,因为Python 试图显示类型的名称:
>>> print r1.rangerr.min
<attribute 'min' of 'rangerr.rangerr' objects>