2017-11-17 107 views
0

我有一個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); 

更新過程使用結構填充預先分配的空間。

回答

2

這是一種方式,但它並不漂亮。​​不在結構中執行變量數組,因此訪問變量數據需要進行一些轉換。

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 
+0

我不知道我完全理解,但它聽起來像是這僅適用,如果我可以設置數據如何被建造。在我的情況下,我不控制數據;它是從第三方API返回的。這是否意味着我不能使用ctypes? – user1219358

+0

@ user1219358我構建了字節緩衝區以模擬您從API獲取的內容。當我有機會時,我會用實際的C API更新示例。 –

+0

@ user1219358測試DLL的更新示例。 –

相關問題