question about C extensions

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);
}
 
R

Ralph Butler

I think I may have figured all this out by looking at examples in the
python source, e.g. xxsubtype.c etc. Nonetheless, I would appreciate
any extra info others might provide.
Thanks again.
--ralph

Ralph said:
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);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top