Help creating extension for C function
Fredrik Lundh
fredrik at pythonware.com
Sat Oct 8 10:22:06 EDT 2005
"Java and Swing" wrote:
>I need to write an extension for a C function so that I can call it
> from python.
>
> C code (myapp.c)
> ======
> typedef unsigned long MY_LONG;
>
> char *DoStuff(char *input, MY_LONG *x) { ... }
>
> so you pass in a string and an array of MY_LONGS...such as
>
> MY_LONGS vals[10] = {....};
> char *input = "this is my input";
> char *result;
>
> result = DoStuff(input, vals);
>
> ...I need to create an extension so that I can call this from Python
> such as...
>
>>> import myapp
>>> vals = [1,2,3,4,5,6,7,8,9,10]
>>> input = "this is my input"
>>> result = myapp.DoStuff(input, vals)
>>> print result
>
> ideally the result would be a String, vals would be a list and input
> would be a string.
$ more module.c
/* $Id$ */
/* a module */
#include "Python.h"
static long*
get_long_array(PyObject* data, int* data_size)
{
int i, size;
long* out;
PyObject* seq;
seq = PySequence_Fast(data, "expected a sequence");
if (!seq)
return NULL;
size = PySequence_Size(seq);
if (size < 0)
return NULL;
if (data_size)
*data_size = size;
out = (long*) PyMem_Malloc(size * sizeof(long));
if (!out) {
Py_DECREF(seq);
PyErr_NoMemory();
return NULL;
}
for (i = 0; i < size; i++)
out[i] = PyInt_AsLong(PySequence_Fast_GET_ITEM(seq, i));
Py_DECREF(seq);
if (PyErr_Occurred()) {
PyMem_Free(out);
out = NULL;
}
return out;
}
static PyObject*
do_stuff(PyObject* self, PyObject* args)
{
int i;
long* vals;
int vals_size;
char* my_result;
char* input;
PyObject* vals_in;
if (!PyArg_ParseTuple(args, "sO:do_stuff", &input, &vals_in))
return NULL;
vals = get_long_array(vals_in, &vals_size);
if (!vals)
return NULL;
if (vals_size != 10) {
PyErr_SetString(PyExc_ValueError, "expected 10 values");
PyMem_Free(vals);
return NULL;
}
/* do stuff */
printf("input = %s\n", input);
for (i = 0; i < 10; i++)
printf("vals[%d] = %ld\n", i, vals[i]);
my_result = "result";
/* done */
PyMem_Free(vals);
return PyString_FromString(my_result);
}
static PyMethodDef functions[] = {
{"do_stuff", do_stuff, METH_VARARGS},
{NULL, NULL}
};
PyMODINIT_FUNC initmodule(void)
{
Py_InitModule4(
"module", functions, "my module", NULL, PYTHON_API_VERSION
);
}
$ more setup.py
# $Id$
# a setup file
from distutils.core import setup, Extension
setup(
name="module",
ext_modules = [Extension("module", ["module.c"])]
)
$ python setup.py build_ext -i
...
$ python
>>> import module
>>> vals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> input = "this is some input"
>>> result = module.do_stuff(input, vals)
input = this is some input
vals[0] = 1
vals[1] = 2
vals[2] = 3
vals[3] = 4
vals[4] = 5
vals[5] = 6
vals[6] = 7
vals[7] = 8
vals[8] = 9
vals[9] = 10
>>> result
'result'
</F>
More information about the Python-list
mailing list