I want to get some string from a C/C++ library with ctypes into python. My code looks like this:
Code in lib:
const char* get(struct something *x)
{
[...]
// buf is a stringstream
return strdup(buf.str().c_str());
}
void freeme(char *ptr)
{
free(ptr);
}
Python code:
fillprototype(lib.get, c_char_p, POINTER(some_model)])
fillprototype(lib.freeme, None, [c_char_p])
// what i want to do here: get a string into python so that i can work
// with it and release the memory in the lib.
c_str = lib.get(some_model)
y = ''.join(c_str)
lib.freeme(c_str)
If i print() c_str, everything is there. Problem is (or seems to be) in the last Python line. I cannot free the memory – the library is getting a wrong pointer. What I am doing wrong here? (And please don’t suggest boost::python or so).
*** glibc detected *** python2: munmap_chunk(): invalid pointer: 0x00000000026443fc ***
As David Schwartz pointed out, if you set restype to
c_char_p, ctypes returns a regular Python string object. A simple way to get around this is to use avoid *and cast the result:string.c:
Python usage:
You can also use a subclass of
c_char_p. It turns out that ctypes doesn’t call thegetfuncfor a subclass of a simple type.The
valueattribute returns the string. You can leave the parameter forfreemeas the more genericc_void_p. That accepts any pointer type or integer address.