Skip to content Skip to sidebar Skip to footer

Does Python Ctypes Supports Size-0 Array?

i have a struct with array[0] inside it.i wonder how can i represent it with ctypes? or if ctypes does not supprt it, are there any other solutions? Any help will be appreciated.

Solution 1:

You can represent a struct like this:

structTest
{
    int size;
    char arr[0];
};

As:

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

But to access the field, you'll need to cast it to a pointer. Assume t is of type ctypes.POINTER(Test):

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

Tested Windows example

x.h

#ifdef TESTAPI_EXPORTS#define TESTAPI __declspec(dllexport)#else#define TESTAPI __declspec(dllimport)#endifstructTest
{
    int size;
    int arr[0];
};

TESTAPI structTest* Test_alloc(int size);
TESTAPI voidTest_free(struct Test* test);

x.c (Compile with "cl /LD x.c")

#include<stdlib.h>#define TESTAPI_EXPORTS#include"x.h"structTest* Test_alloc(int size)
{
    structTest* 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;
}

voidTest_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)

Output

100100120023003400450056006700780089009

Post a Comment for "Does Python Ctypes Supports Size-0 Array?"