I’m trying to pass a structure pointer to the API wrapper, Where the struct is containing float pointer member. I’m not sure that how we can pass float pointer value to the structure.
/Structure/
class input_struct (ctypes.Structure): _fields_ = [ ('number1', ctypes.POINTER(ctypes.c_float)), ('number2', ctypes.c_float), #('option_enum', ctypes.POINTER(option)) ]
/wrapper/
init_func = c_instance.expose_init init_func.argtypes = [ctypes.POINTER(input_struct)] #help(c_instance) inp_str_ptr = input_struct() #inp_str_ptr.number1 = cast(20, ctypes.POINTER(ctypes.c_float)) # want to pass pointer inp_str_ptr.number1 = 20 # want to pass as float pointer inp_str_ptr.number2 = 100 c_instance.expose_init(ctypes.byref(inp_str_ptr)) c_instance.expose_operation()
Advertisement
Answer
You can either create a c_float
instance and initialize with a pointer to that instance, or create a c_float
array and pass it, which in ctypes
imitates a decay to a pointer to its first element.
Note that ctypes.pointer()
creates pointers to existing instances of ctypes
objects while ctypes.POINTER()
creates pointer types.
test.c – for testing
#ifdef _WIN32 # define API __declspec(dllexport) #else # define API #endif typedef struct Input { float* number1; float number2; } Input; API void expose_init(Input* input) { printf("%f %fn",*input->number1, input->number2); }
test.py
import ctypes class input_struct (ctypes.Structure): _fields_ = (('number1', ctypes.POINTER(ctypes.c_float)), ('number2', ctypes.c_float)) c_instance = ctypes.CDLL('./test') init_func = c_instance.expose_init # Good habit to fully define arguments and return type init_func.argtypes = ctypes.POINTER(input_struct), init_func.restype = None inp_str_ptr = input_struct() num = ctypes.c_float(20) # instance of c_float, similar to C "float num = 20;" inp_str_ptr.number1 = ctypes.pointer(num) # similar to C "inp_str_ptr.number1 = #" inp_str_ptr.number2 = 100 c_instance.expose_init(ctypes.byref(inp_str_ptr)) # similar to C "float arr[1] = {30}; inp_str_ptr = arr;" inp_str_ptr.number1 = (ctypes.c_float * 1)(30) c_instance.expose_init(ctypes.byref(inp_str_ptr))
Output:
20.000000 100.000000 30.000000 100.000000