ctypes:如何将结构数组定义为另一个结构的字段?
问题描述:
我有一个C结构如下所示:ctypes:如何将结构数组定义为另一个结构的字段?
typedef struct _DXYZ {
DXYZSTATE State[];
} DXYZ, *PDXYZ
本质上,的DXYZSTATE
阵列,未知大小的。
当我试图在中声明这个结构时,我不知道该怎么做。
class DXYZ(Structure):
_fields_ = [
('State', ???)
]
我用什么来表示未知大小的结构数组?
如果有帮助,它在C中使用的示例如下,malloc'd与其他地方提供的大小。
CurrentState = (PDXYZ) malloc(statesize);
err = update(CurrentState);
更新过程使用结构填充预先分配的空间。
答
这是一种方式,但它并不漂亮。不在结构中执行变量数组,因此访问变量数据需要进行一些转换。
test.c实现一个返回变量结构数据的测试函数。在这种情况下,我硬编码大小为4的返回数组,但它可以是任何大小。
#include <stdlib.h>
typedef struct STATE {
int a;
int b;
} STATE;
typedef struct DXYZ {
int count;
STATE state[];
} DXYZ, *PDXYZ;
__declspec(dllexport) PDXYZ get(void)
{
PDXYZ pDxyz = malloc(sizeof(DXYZ) + sizeof(STATE) * 4);
pDxyz->count = 4;
pDxyz->state[0].a = 1;
pDxyz->state[0].b = 2;
pDxyz->state[1].a = 3;
pDxyz->state[1].b = 4;
pDxyz->state[2].a = 5;
pDxyz->state[2].b = 6;
pDxyz->state[3].a = 7;
pDxyz->state[3].b = 8;
return pDxyz;
}
__declspec(dllexport) void myfree(PDXYZ pDxyz)
{
free(pDxyz);
}
test.py
from ctypes import *
import struct
class State(Structure):
_fields_ = [('a',c_int),
('b',c_int)]
class DXYZ(Structure):
_fields_ = [('count',c_int), # Number of state objects
('state',State * 0)] # Zero-sized array
# Set the correct arguments and return type for the DLL functions.
dll = CDLL('test')
dll.get.argtypes = None
dll.get.restype = POINTER(DXYZ)
dll.myfree.argtypes = POINTER(DXYZ),
dll.myfree.restype = None
pd = dll.get() # Get the returned pointer
d = pd.contents # Dereference it.
print('count =',d.count)
# Cast a pointer to the zero-sized array to the correct size and dereference it.
s = cast(byref(d.state),POINTER(State * d.count)).contents
for c in s:
print(c.a,c.b)
dll.myfree(pd)
输出:
count = 4
1 2
3 4
5 6
7 8
我不知道我完全理解,但它听起来像是这仅适用,如果我可以设置数据如何被建造。在我的情况下,我不控制数据;它是从第三方API返回的。这是否意味着我不能使用ctypes? – user1219358
@ user1219358我构建了字节缓冲区以模拟您从API获取的内容。当我有机会时,我会用实际的C API更新示例。 –
@ user1219358测试DLL的更新示例。 –