I have below code which tries to create a new type and use getter method to access value.
#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);
}
I can import the new type
import rangerr as r1
but accessing the getting method crashes
print r1.rangerr.min
EDIT:
(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)
You need to define
tp_name
. At the moment this field is not set at all.You're getting the core dump here, because Python tries to display the name of the type: