R
Ralph Butler
Hi:
I have a question about extending python with C. I have read the docs
and done some googling, but come up short on this particular (small)
problem. I want to write a c extension to int. In particular, I want
to grab the memory for the int from an alternative heap. I am confused
about 2 things: (1) Do I need to call the __init__ function for int
itself, and if so, how do I do that? (2) Do I supply my own tp_alloc
function to retrieve the memory for my new elements, and if so, what
should it look like? (Assume for the moment that I simply plan to do a
malloc.)
I have attached code that does most of the work and has my initials
(RMB) at a couple of the pieces of code I think I may need.
Any pointers to fairly specific examples would be appreciated. I have
found non-specific examples a bit confusing.
Thanks.
--ralph
from distutils.core import setup, Extension
setup (name = "intext",
version = "1.0",
maintainer = "rbutler",
maintainer_email = "(e-mail address removed)",
description = "shared memory objects",
ext_modules = [Extension('intext',sources=['intext.c'])]
)
#!/usr/bin/env python
# inherit from int
import intext
x = intext.INTEXT(44)
print type(x)
print x
print int(x) + 33
#include <Python.h>
static PyTypeObject *INTEXT_type_p;
#define PyINTEXT_Check(obj) ((obj)->ob_type == INTEXT_type_p)
typedef struct newtypeobjectstruct
{
PyObject_HEAD
int *intextp;
} pyintext;
static PyObject *pyintext_tp_alloc(PyTypeObject *type, int nitems)
{
printf("tpalloc: nitems=%d\n",nitems);
// RMB: grab memory for the object
return (PyObject *) NULL;
}
static int pyintext_init(pyintext *self, PyObject *args)
{
int iv;
if ( ! PyArg_ParseTuple(args,"i",&iv))
return -1;
printf("init iv=%d\n",iv);
// RMB: invoke the super class __init__ ??
return 0;
}
static char INTEXT_type_doc[] = "intext type doc";
PyTypeObject INTEXTType = {
PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */
"intext.INTEXT", /* tp_name */
sizeof(pyintext), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
(printfunc) NULL, /* 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_HAVE_CLASS, /* tp_flags */
INTEXT_type_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PyInt_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc) pyintext_init, /* tp_init */
pyintext_tp_alloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
};
static char intext_module_doc[] = "intext module doc";
static struct PyMethodDef intext_module_methods[] = {
{NULL, NULL, 0, NULL}
};
void initintext(void)
{
PyObject *m;
/* Create the module and add the functions */
INTEXT_type_p = &INTEXTType;
INTEXTType.ob_type = &PyType_Type;
if (PyType_Ready(INTEXT_type_p) < 0)
return;
m = Py_InitModule3("intext",intext_module_methods,intext_module_doc);
if (!m)
{
printf("Py_InitModule3 failed\n");
return;
}
Py_INCREF(INTEXT_type_p);
PyModule_AddObject(m, "INTEXT", (PyObject *) & INTEXTType);
}
I have a question about extending python with C. I have read the docs
and done some googling, but come up short on this particular (small)
problem. I want to write a c extension to int. In particular, I want
to grab the memory for the int from an alternative heap. I am confused
about 2 things: (1) Do I need to call the __init__ function for int
itself, and if so, how do I do that? (2) Do I supply my own tp_alloc
function to retrieve the memory for my new elements, and if so, what
should it look like? (Assume for the moment that I simply plan to do a
malloc.)
I have attached code that does most of the work and has my initials
(RMB) at a couple of the pieces of code I think I may need.
Any pointers to fairly specific examples would be appreciated. I have
found non-specific examples a bit confusing.
Thanks.
--ralph
from distutils.core import setup, Extension
setup (name = "intext",
version = "1.0",
maintainer = "rbutler",
maintainer_email = "(e-mail address removed)",
description = "shared memory objects",
ext_modules = [Extension('intext',sources=['intext.c'])]
)
#!/usr/bin/env python
# inherit from int
import intext
x = intext.INTEXT(44)
print type(x)
print x
print int(x) + 33
#include <Python.h>
static PyTypeObject *INTEXT_type_p;
#define PyINTEXT_Check(obj) ((obj)->ob_type == INTEXT_type_p)
typedef struct newtypeobjectstruct
{
PyObject_HEAD
int *intextp;
} pyintext;
static PyObject *pyintext_tp_alloc(PyTypeObject *type, int nitems)
{
printf("tpalloc: nitems=%d\n",nitems);
// RMB: grab memory for the object
return (PyObject *) NULL;
}
static int pyintext_init(pyintext *self, PyObject *args)
{
int iv;
if ( ! PyArg_ParseTuple(args,"i",&iv))
return -1;
printf("init iv=%d\n",iv);
// RMB: invoke the super class __init__ ??
return 0;
}
static char INTEXT_type_doc[] = "intext type doc";
PyTypeObject INTEXTType = {
PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */
"intext.INTEXT", /* tp_name */
sizeof(pyintext), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
(printfunc) NULL, /* 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_HAVE_CLASS, /* tp_flags */
INTEXT_type_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PyInt_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc) pyintext_init, /* tp_init */
pyintext_tp_alloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
};
static char intext_module_doc[] = "intext module doc";
static struct PyMethodDef intext_module_methods[] = {
{NULL, NULL, 0, NULL}
};
void initintext(void)
{
PyObject *m;
/* Create the module and add the functions */
INTEXT_type_p = &INTEXTType;
INTEXTType.ob_type = &PyType_Type;
if (PyType_Ready(INTEXT_type_p) < 0)
return;
m = Py_InitModule3("intext",intext_module_methods,intext_module_doc);
if (!m)
{
printf("Py_InitModule3 failed\n");
return;
}
Py_INCREF(INTEXT_type_p);
PyModule_AddObject(m, "INTEXT", (PyObject *) & INTEXTType);
}