python ctypes支持size-0数组吗?

时间:2015-02-28 09:55:22

标签: python-3.x ctypes

我在其中有一个带有数组[0]的结构。我想知道如何用ctypes表示它?或者如果ctypes不支持它,还有其他解决方案吗?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

您可以代表这样的结构:

struct Test
{
    int size;
    char arr[0];
};

如:

class Test(ctypes.Structure):
    _fields_ = [('size',ctypes.c_int),
                ('arr',ctypes.c_byte*0)]

但要访问该字段,您需要将其强制转换为指针。假设t的类型为ctypes.POINTER(Test)

arr = ctypes.cast(t.contents.arr,POINTER(c_byte))
for i in range(t.contents.size):
    print(arr[i])

经过测试的Windows示例

x.h

#ifdef TESTAPI_EXPORTS
#define TESTAPI __declspec(dllexport)
#else
#define TESTAPI __declspec(dllimport)
#endif

struct Test
{
    int size;
    int arr[0];
};

TESTAPI struct Test* Test_alloc(int size);
TESTAPI void Test_free(struct Test* test);

x.c(用“cl / LD x.c”编译)

#include <stdlib.h>
#define TESTAPI_EXPORTS
#include "x.h"

struct Test* Test_alloc(int size)
{
    struct Test* t = malloc(sizeof(struct Test) + size * sizeof(int));
    if(t != NULL)
    {
        int i;
        t->size = size;
        for(i = 0; i < size; ++i)
            t->arr[i] = i*1000+i;
    }
    return t;
}

void Test_free(struct Test* test)
{
    free(test);
}

x.py

from ctypes import *

class Test(Structure):
    _fields_ = [('size',c_int),
                ('arr',c_int*0)]

dll = CDLL('x')

Test_alloc = dll.Test_alloc
Test_alloc.argtypes = [c_int]
Test_alloc.restype = POINTER(Test)

Test_free = dll.Test_free
Test_free.argtypes = [POINTER(Test)]
Test_free.restype = None

t = Test_alloc(10)
print(t.contents.size)
arr = cast(t.contents.arr,POINTER(c_int))
for i in range(t.contents.size):
    print(arr[i])
Test_free(t)

输出

10
0
1001
2002
3003
4004
5005
6006
7007
8008
9009