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