c bindings

Sebastien LOISEL loisel at scylla.math.mcgill.ca
Sun Jul 8 20:38:22 EDT 2001


Thank you Thomas for your invaluable comments,

I have been tracking down my problems and it seems that the code I had
sent was ok. It was important for me to have other people, who are
undoubtedly much smarter than I am at this, tell me that it was ok.
Knowing that I do this correctly allows me to concentrate on what I'm
doing wrong, which is elsewhere. And please be assured that when I am
stumped again, I will reach out again for help from the community.

That being said, let me beg to differ: I am one of those people who think
that returning 0 is actually better than returning NULL and I also like
my one-line for loops.

Oddness in the code (eg, the ret_size check) is caused by the automatic
code generator.

Sebastien Loisel -- http://www.loisel.org/
Ph.D. Student -- McGill University -- Department of Mathematics
Graphics Architect -- Nvidia Corporation

On Mon, 9 Jul 2001, Thomas Wouters wrote:

> On Fri, Jul 06, 2001 at 01:25:21PM -0700, Sebastien Loisel wrote:
> 
> 
> > I am writing an extension module. For this purpose, I have written a very
> > short code generator, to create wrappers around my C library. For some
> > simple test cases, it seems to work fine, but I am encountering core dumps
> > with a more complete program.
> 
> Your best bet is really to examine the corefile in gdb, it can often point
> you directly to the problem. Changing the 'gtc_must_malloc's in your example
> to just plain 'malloc', your code works, and you don't give any clues about
> how to break it. Still, here are some hints.
> 
> > static PyObject *example_py(PyObject *self, PyObject *args)
> > {
> >   int j;
> >   PyObject *_;
> 
> Bad style... Don't use _* names unless you know what you're doing, it might
> clash with something platformish, 'hidden'.
> 
> >   if(!PyArg_ParseTuple(args,"O", &param_helper)) return 0;
> 
> Bad style... Your function returns a pointer, you should return 'NULL', not
> 0. Unlikely to be the cause of the problem, though.
> 
> >   ret_size=param_size;
> >   ret=gtc_must_malloc(sizeof(float)*ret_size);
> >   for(j=0;j<ret_size;j++) ret[j]=param[j]+j/2.0;
> >   if(ret_size<0) abort();
> 
> Too late for this check. If reg_size is smaller than 0, the malloc() would
> already have failed and you die in the for loop. What's more, you didn't
> check the return value of the malloc. And cramming the for statement and
> body all on one line is, well, bad style :-)
> 
> >   ret_list=PyList_New(ret_size);
> >   for(j=0;j<ret_size;j++) {
> >     PyList_SetItem(ret_list,j,PyFloat_FromDouble(ret[j]));
> 
> Note: you can use PyList_SETITEM here, it works the same but is faster, and
> you already know the list is a real list and is long enough to hold the
> result.
> 
> >   free(ret);
> >   return ret_list;
> > }
> > static PyMethodDef example_methods[] = {
> >   {"example",example_py,1},
> 
> Better use the define 'METH_VARARS' than a literal 1 here... not just better
> style, but more guaranteed to work later :)
> 
> >   {0,0} // sentinel
> 
> And these should be NULL's.
> 
> -- 
> Thomas Wouters <thomas at xs4all.net>
> 
> Hi! I'm a .signature virus! copy me into your .signature file to help me spread!
> 





More information about the Python-list mailing list