Thanks, the method did work. To my understanding, "ALL_RESULTS" is used to prevent pypy GC the pointing buffer. And thus, it is the C callback function's responsibility to free the buffer. Am I right?
On Thursday, May 14, 2015 at 4:14:07 PM UTC+8, Armin Rigo wrote: > > Hi Yicong, > > (CC to the cffi mailing list) > > On 14 May 2015 at 05:02, Yicong Huang <hengh...@gmail.com <javascript:>> > wrote: > > We had a python function that return a string value. The function will > > callback in C code. > > The below is an example of the code: > > > > @ffi.callback("char *(char *, char *)") > > def strconcat(x, y): > > x1 = ffi.string(x) > > y1 = ffi.string(y) > > print x1 + y1 > > return x1 + y1 > > > > The error messages are: > > Trying to convert the result back to C: > > TypeError: initializer for ctype 'char *' must be a cdata pointer, not > str > > > > How could we convert the return python string value to C char*? > > This is not obvious, because you have problems writing it in C too: > returning a "char *" is only possible when you return some constant > string literal (only in C, can't do that with cffi), or when you > allocate the resulting string and keep it alive for as long as the > caller needs it (and you don't really know how long that is). > > If you have a callback to a C library that you didn't write, it must > be written in its documentation. If it is not, and you really have no > choice, then you have to guess. The following would work in all cases > but leak the strings by never releasing them: > > ALL_RESULTS = [] > @ffi.callback("char *(char *, char *)") > def strconcat(x, y): > x1 = ffi.string(x) > y1 = ffi.string(y) > print x1 + y1 > p = ffi.new("char[]", x1 + y1) > ALL_RESULTS.append(p) > return p > > There are chances that it works as expected if you only keep alive the > last returned result; try it out, but no guarantee. > > > A bientôt, > > Armin. >
_______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev