2

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()

1 Answer 1

2

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 %f\n",*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
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @Mark Tolonen, it helped! Also i'm trying to write wrapper for same code using PyBind11, but there i have the same problem in handling. [link]stackoverflow.com/questions/72853557/… Inputs are most welcome...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.