ctypes:如何将一个结构的数组定义为另一个结构的字段? [英] ctypes: How do I define an array of a structure as a field of another structure?

查看:81
本文介绍了ctypes:如何将一个结构的数组定义为另一个结构的字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下所示的C结构:

I have a C structure that looks like the following:

typedef struct _DXYZ {
    DXYZSTATE State[];
} DXYZ, *PDXYZ

基本上,是 DXYZSTATE的数组,大小未知。

Essentially, an array of DXYZSTATE, of unknown size.

当我尝试在 ctypes 中声明此结构时,我不确定该怎么办。

When I try to declare this structure in ctypes, I'm not sure what to do.

class DXYZ(Structure):
    _fields_ = [
        ('State', ???)
    ]

我用什么来表示结构的未知大小的数组?

What do I use to represent an unknown sized array of a structure?

如果有帮助,可以在C中使用以下示例,并在其他地方提供其大小。

If it helps, the example for its use in C is the following, malloc'd with a size provided elsewhere.

CurrentState = (PDXYZ) malloc(statesize);
err = update(CurrentState);

更新proc用该结构填充预分配的空间。

The update proc fills in the pre-allocated space with the structure.

推荐答案

这是一种方法,但是并不美观。 ctypes 不会在结构中执行变量数组,因此访问变量数据需要进行强制转换。

Here's a way but it isn't pretty. ctypes doesn't do variable arrays in a structure so to access the variable data requires some casting.

test.c 实现返回可变结构数据的测试功能。在这种情况下,我硬编码了一个大小为4的返回数组,但它可以是任何大小。

test.c Implements a test function returning the variable structure data. In this case I hard-coded a return array of size 4 but it could be any size.

#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

这篇关于ctypes:如何将一个结构的数组定义为另一个结构的字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆