Why does Python crash when returning a C string?

Here is my C code, I made it public. When I load the shared lib in Python and execute the Python code below, I crashed. What for?

extern "C" { PyObject* foo2(char* b) { return Py_BuildValue("s", b); } } 

And here is what I do in Python:

  from ctypes import * d = cdll.LoadLibrary('./foo.so') d.foo2.restype = c_char_p v = d.foo2('hello world') print pythonapi.PyString_Size(v) 

If this helps, I am on Python2.6.

+5
source share
2 answers

Your problem is that you are lying about the return type:

 d.foo2.restype = c_char_p 

The actual return type is PyObject * . But ctypes will see that c_char_p , PyObject * to char * , and then try to convert this char * to a string with PyString_FromString , which will read who knows that arbitrary bytes until it reaches the NUL character.

A way to specify PyObject * with py_object .

Also, you probably want to install argtype s. And this time it really is c_char_p :

 d = cdll.LoadLibrary('./foo.so') d.foo2.argtypes = [c_char_p] d.foo2.restype = py_object 

But, as interjay points out in a comment, it's a little silly to build a C library that uses the Python C API and then calls it through ctypes . This is sometimes useful, but usually the solution is to just finish creating the C extension module instead of doing 80% of the work without any benefit ...

+9
source

You tell cdll that the function returns char* , but actually returns PyObject* . The two should be in agreement.

+4
source

All Articles