2014-01-13 109 views
1

我想编写一个函数,它可以将本地Python列表或ctypes数组作为参数。我可以检测前者使用确定一个对象是否是一个ctypes数组

isinstance(the_parameter, list) 

如何确定给定的变量是否引用ctypes数组?

编辑:在一个ctypes数组传递给我的函数的情况下,我只是想把它变成一个列表。我意识到,我可以做

the_list = list(the_parameter) 

,这将给列表不管the_parameter是否是一个Python列表或一个ctypes阵列。我会在这里留下这个问题,因为我仍然对答案感兴趣。

回答

6

isinstance(the_parameter, ctypes.Array)将检查一个ctypes数组。

的ctypes定义了以下简单的标量类型(注意,它们是私有的):

_SimpleCData # _type_: 'P' for void * 
_Pointer  # _type_: ctypes.c_int 
_CFuncPtr # _flags_, _restype_, _argtypes_, _check_retval_ 

虽然您可以直接继承这些类型的,在大多数情况下,你应该使用现有的子类和工厂功能,如c_void_pPOINTERCFUNCTYPE

ctypes的定义了以下聚合类型:

Array  # _type_, _length_ 
Structure # _fields_, _anonymous_, _pack_, _swappedbytes_ 
Union  # _fields_, _anonymous_, _pack_, _swappedbytes_ 

Array亚类通常通过使用操作者*序列重复创建的,例如IntArray = c_int * 10。您可以改为使用以下内容:

class IntArray(ctypes.Array): 
    _type_ = ctypes.c_int 
    _length_ = 10 

a = IntArray(*range(10)) 
a_list = a[:] 
2

最简单的(也可能是大多数Pythonic)方法是将参数作为一个ctypes数组来处理,然后捕获由于不同行为而导致参数不是ctypes数组时会引发的异常。由于ctypes数组实现了迭代,因此只要您在Python端正确定义了structs和ctypes数组,就可以在大多数情况下交替使用Python列表和ctypes数组。这是假设你有一个实际的ctypes数组,而不仅仅是一个指向C端数组的指针,但是在那些情况下,你必须以某种方式跟踪数组的长度,并且ctypes指针可以像数组一样索引所以如果你必须提供一个长度,你可以用size作为你的函数的参数,默认为None,然后使用for i in range(size or len(the_parameter)): the_parameter[i] # do stuff

相关问题