python-3.xpython-cffi

Python passing read-only char ** as argument to a function


I have a C library function that expects a char const ** argument, such as:

void set_values(void* object, char const ** values, int dim1, int dim2);

Where values is an array of dim1*dim2 length pointing to null terminated string values.

When I try to call this function using cffi/ctypes, the Python code below results in error:

LP_c_char  = ctypes.POINTER(ctypes.c_char)

dim1 = 2
dim2 = 3
values = ('1.0', '2.0', '1.2', '2.2', '1.5', '2.5')

values_ptr = (LP_c_char * (dim1 * dim2))()
for i, value in enumerate(values):
    values_ptr[i] = ctypes.create_string_buffer(value.encode('utf-8'))

mylib.set_values(object, values_ptr, dim1, dim2)

The result is the error below at mylib.set_values(...) line:

TypeError: initializer for ctype 'char * *' must be a cdata pointer, not LP_c_char_Array_6

Sadly values cannot be a double* array because the library accepts variable names and expressions.

I was following this old thread. I'm using Python 3.7.2 and cffi 1.14.0.

Can someone point out what I'm doing wrong here?


Solution

  • You can't mix ctypes and cffi like that. They are two different projects. In this case, you're trying to call a function exposed by cffi but passing arguments that are ctypes objects. Try building cffi objects instead, e.g. with ffi.new().