>>> from ctypes import *
>>> class A(Structure):
... _fields_ = [('a', c_int), ('b', c_int)]
... def __init__(self, x):
... self.a = x + 1
... self.b = x + 2
...
>>> a = A(1)
>>> a.a
2
>>> a.b
3
>>> b = (A * 2)(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected A instance, got int
Run Code Online (Sandbox Code Playgroud)
我试图在python中构造一个C结构数组,并希望为数组中的每个元素调用构造函数.我怎么能做到这一点?
该错误确切地解释了问题,但是以一种稍微复杂的方式:
初始化此类数组的正确方法如下:
structs = [A(1, 2), A(1, 2)]
array = (A * 2)(*structs)
Run Code Online (Sandbox Code Playgroud)
或者,如果您可以在数组构造函数中定义它们,如下所示:
array = (A * 2)(A(1, 2), A(1, 2))
Run Code Online (Sandbox Code Playgroud)
现在,为什么这样做,你的解决方案不适用?由于我传递一个实例的A每个参数的构造A * 2,这是一个数组A.该数组需要A为每个传递的参数提供一个实例,这正是错误消息.它不期望将参数转换为A,它期望A自己的实例.
一步一步的方法如下:
from ctypes import *
class A(Structure):
_fields_ = [('a', c_int), ('b', c_int)]
# this create a class which expects 2 A instances
a_array_factory = A * 2
# our first A instance
struct_1 = A(1, 2)
# our second A instance
struct_2 = A(2, 3)
# initialize our array
array = a_array_factory(struct_1, struct_2)
Run Code Online (Sandbox Code Playgroud)
编辑:
由于结构没有本机Python类型,据我所知,没有创建中间结构的解决方案.根据Python 文档,具有C基元的唯一本机类型如下:
ctypes type C type Python type
c_bool _Bool bool (1)
c_char char 1-character string
c_wchar wchar_t 1-character unicode string
c_byte char int/long
c_ubyte unsigned char int/long
c_short short int/long
c_ushort unsigned short int/long
c_int int int/long
c_uint unsigned int int/long
c_long long int/long
c_ulong unsigned long int/long
c_longlong __int64 or long long int/long
c_ulonglong unsigned __int64 or unsigned long long int/long
c_float float float
c_double double float
c_longdouble long double float
c_char_p char * (NUL terminated) string or None
c_wchar_p wchar_t * (NUL terminated) unicode or None
c_void_p void * int/long or Nonee or None
Run Code Online (Sandbox Code Playgroud)