jaw
jaw

Reputation: 1032

How to get ctypes type object from an ctypes array

Actually, I'm trying to convert ctypes arrays to python lists and back.

If found this thread. But it assumes that we know the type at compile time.

But is it possible to retrieve a ctypes type for an element?

I have a python list that contains at least one element. I want to do something like that

import ctypes
arr = (type(pyarr[0]) * len(pyarr))(*pyarr)

This obviously doesn't work because type() doesn't return a ctypes compatible class. But even if the list contains object created directly from ctypes, the above code doesn't work because its an object instance of the type.

Is there any way to perform this task?

[EDIT]

Ok, here is the code that works for me. I'm using it to convert input paraters from comtypes server method to python lists and return values to array pointers:

def list(count, p_items):
    """Returns a python list for the given times represented by a pointer and the number of items"""
    items = []
    for i in range(count):
        items.append(p_items[i])
    return items

def p_list(items):
    """Returns a pointer to a list of items"""
    c_items = (type(items[0])*len(items))(*items)
    p_items = cast(c_items, POINTER(type(items[0])))

    return p_items

As explained before, p_list(items) requires at least one element.

Upvotes: 1

Views: 4362

Answers (1)

Mark Tolonen
Mark Tolonen

Reputation: 178389

I don't think that's directly possible, because multiple ctypes types map to single Python types. For example c_int/c_long/c_ulong/c_ulonglong all map to Python int. Which type would you choose? You could create a map of your preferences:

>>> D = {int:c_int,float:c_double}
>>> pyarr = [1.2,2.4,3.6]
>>> arr = (D[type(pyarr[0])] * len(pyarr))(*pyarr)
>>> arr
<__main__.c_double_Array_3 object at 0x023540D0>
>>> arr[0]
1.2
>>> arr[1]
2.4
>>> arr[2]
3.6

Also, the undocumented _type_ can tell the type of a ctypes array.

>>> arr._type_
<class 'ctypes.c_double'>

Upvotes: 3

Related Questions