[pypy-dev] Declaring a function that returns a string in CFFI

Elefterios Stamatogiannakis estama at gmail.com
Thu Sep 25 09:06:18 CEST 2014


On 24/09/14 20:13, Armin Rigo wrote:
> Hi,
>
> On 23 September 2014 14:54, Eleytherios Stamatogiannakis
> <estama at gmail.com> wrote:
>>> p = clib.getString(...)        # a "char *"
>>> length = clib.strlen(p)     # the standard strlen() function from C
>>> b = unicode(ffi.buffer(p, length), 'utf-8')
>>
>> I've tried that, and the overhead of the second call is more or less equal
>> to the cost of the copy when using ffi.string.
>
> You cannot have a C function returning a 'char[]'.  That's why you
> need to declare it returning a 'char *', and then you don't know the
> length.  Sorry, it's the way C works; there is nothing I can do about
> that :-)

Thank you for clarifying. I thought that ffi.buffer scanned for the \0 
to find the end of the string for "char[]" types.

> Occasionally, we see C functions with this kind of signature:
>
>     size_t getString(xxx, char **result);
>
> This would return the length, and use 'result' as an output parameter,
> to store into '*result' a pointer to the string.  If you really care
> about performance, then you might want to change the C library you're
> binding to in order to do that.

Unfortunately, the C library that i use (libsqlite3) does not provide a 
function like that :( . It has a function that returns the size of the 
string, but in my tests the overhead of doing another CFFI call (to find 
the size) is greater than doing the 2nd copy (depending on the average 
string size).

We are doing 100s of millions of string passing calls back and forth 
from the libsqlite3 library, so any way to improve the efficiency of 
this case would be more than welcome :) .

Best regards,

l.



More information about the pypy-dev mailing list