calling Pyrex results from C
Paul Prescod
paul at prescod.net
Wed Jan 21 11:23:53 EST 2004
Kyler Laird wrote:
>
> Pyrex:
> cdef public image_file_open(char* image_filename):
> return(Image.open(image_filename))
>
> cdef public image_size(image_PIL):
> return(Image.size)
>
> cdef public char* string(x):
> s = str(x)
> return(s)
>
> my C:
> void *im, *im_size;
> im = image_file_open(input_filename);
> im_size = image_size(im);
> printf("im=%s\n", string(im));
> printf("im_size=%s\n", string(im_size));
>
> The first call to string() succeeds but the second one fails. I
> suspect that I've expected too much of Pyrex again. Do I need to
> allocate memory, manipulate reference counts or something like
> that?
First, I'd suggest that "integer" is a perfectly good type in both C and
Pyrex so you shouldn't pass around Python objects representing integers.
Second, you aren't checking the return codes of your functions and C has
no exception handling, tracebacks, etc. image_size is probably returning
0 because it is probably throwing an exception because you are asking
for the size attribute of the Image class rather than the image_PIL object.
You actually would have gotten a Pyrex error on your console if your
function were defined to return "int" or "void" because Pyrex would KNOW
that there's no way you are doing exception handling so it would try to
compensate by printing exceptions to the console. But I wouldn't depend
on that feature because it doesn't help for functions that really should
return objects. Better to check your return values.
Once I fix the Image/Image_PIL error your code runs okay on my computer.
But you are walking on thin ice and may just be lucky. It is simply
not possible to work with strings generated at runtime in C without
worrying about memory allocation sometime. In this case I have the
strong suspicion that the string() function is either creating and
destroying a string object and then returning you a pointer to the dead
object's internal memory buffer (bad news!) or simply losing a reference
to the (still living) string object: still not a good thing. Eyeballing
the code I believe the former is the issue. You could check for sure by
adding some printf's to the generated code to look at __pyx_v_s->ob_refcnt.
Why not let Python do the "print" rather than using "printf".
Paul Prescod
More information about the Python-list
mailing list