简体   繁体   中英

python - ctypes, retrieve value of void pointer sent to shared c library

Im calling a cpp function from dll with ctypes

the function definition is

int foo(strc *mystrc, int *varsize);

And the structure:

typedef struct
{
    int type;
    int count;
    void *value;
} strc;

So what I tried in python was to define:

class strc(ctypes.Structure):
    _fields_ = [('type', ctypes.c_int),
                ('count', ctypes.c_int),
                ('value', ctypes.c_void_p)]

And to call the function as

varsize = ctypes.c_int()
mystrc = strc()
foo(ctypes.byref(mystrc), ctypes.byref(varsize))

I can perfectly call the function and retrieve all values except for the "value". It should be an array of variables indicated by the "type", have size "varsize" and be an array of "count" variables.

How can I retrieve what is indicated by the void pointer?

template<class T> void iterate_strc_value(const void* value, int size)
{
    const T* element = reinterpret_cast<const T*>(value);
    for(int offset = 0; offset != size; ++offset)
        *(element + offset) // at this point you have the element at the offset+1th position
}

switch(strc_var.type)
{
    case 0: iterate_strc_value<char>(strc_var.value, element_count); break;
    case 1: iterate_strc_value<int>(strc_var.value, element_count); break;
    case 2: iterate_strc_value<std::string>(strc_var.value, element_count); break;
    default: // invalid type -> maybe throw exception within python?!
}

The value pointer is the pointer that you also named value , while size specifies the amount of elements within the array. The size of the type is not needed, as the size of your types is known at compile time.

Basically the function just converts the void* to a pointer of your desired type and then uses pointer arithmetic to iterate over the array. This approach is general enough to just iterate over any void* which points to an array as long as you know it's size. You could also add a third argument as a callback which performs the given action on each element to keep specialized code outside of the template function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM