Need help with C extension module

Ken Seehart pythonic at seehart.com
Tue Sep 13 04:42:06 EDT 2005


chris wrote:
> This is my first attempt at undertaking a C extension module.  I want
> to wrap an existing C library so I can call the functions from Python.
> There are only two functions I'm interested in calling.  I did mess
> with Pyrex a bit and Swig, to no avail, so I turned to doing it by
> hand.  Using the example in Programming Python, I did get the easier of
> the two functions working--only takes a string parameter.  I'm stuck
> now on the other function and not sure how to wrap it, because it
> involves some structs.  Here's a simplified version of the C:
> 
> struct In
> {
>   int x;
>   char* s;
>   ... (only primitive data types)
> };
> 
> struct Out
> {
>   int y;
>   char* s;
>   ... (only primitive data types)
> };
> 
> Out* func(In* x, Out* y);
> 
> So the function takes pointers to the two structs, and fills out the
> output struct and also returns the pointer to it.  I would envision the
> Python looking like
> 
> in = In()
> in.y = 1
> in.s = "abc"
> ...
> 
> out = func(in)
> 
> maybe?  Just no idea how to deal with the structs in the C extension
> module code.
> 
> Any tips appreciated.
> 
> Thanks,
> Chris
> 

Since others have responded about Pyrex, I'll just add my two cents,
which may or not apply to you.

The idea of filling in a struct, passing it to a function, then
returning a struct, is a typical c-ism.  If the only purpose of the
structs is to pass data to the function and receive the result, read on.
  On the other hand, if the structures represent "things" in the
object-oriented sense, just ignore what I am saying.

I would wrap the function such that the python code simply takes a set
of parameters and returns a tuple.  This is much more pythonic, and much
easier to code.

y,s,... = func(x,s,...)

My untested pseudocode would look something like this:

static PyObject *map_sweep(map__object *self, PyObject *args)
{
   In input;
   Out output;

   if (PyArg_ParseTuple(args, "is...", &(In.x), &(In.s), ...))
   {
     return NULL;
   }

   func(&In, &Out);

   return Py_BuildValue("is...", Out.y, Out.s, ...);
}






More information about the Python-list mailing list