I have a bytes string which is passed into a cython method, and I need to pass it into a c function:
def stuff(bytes b):
#b is b'something'
some_c_function(b, len(b))
The pointer I passed in is saved to some struct inside C-land. By the time it’s used, b has disappeared, so I get a segmentation fault. How do I keep it alive outside of the function?
I tried something like this:
from libc.stdlib import malloc, memcpy
def stuff(bytes b):
cdef char *data
data_len = len(b)
data = malloc(data_len)
memcpy(data, b, data_len)
some_c_function(data, data_len)
But I get an error on the malloc call: Obtaining char * from temporary Python value.
You need to
cimportthemallocfunction, otherwise Cython handles the import as default Python import and thinksmallocis a ordinary Python function.data_lenshould belen(b) + 1and the last byte must be set to0, i.e.data[data_len - 1] = 0. This is the way how a string is terminated in C/C++.After you’ve
cimport-edmallocand Cython treats the function as a C-function, you will need to make a cast, otherwise the Cython compiler will complain.data = <char*> malloc(data_len)What you have
malloc-ed, needs to be freed by yourself. Ensure that this will happen.