ctypes and flexible (zero-length) arrays
Dear lazyweb, I’ve been racking my brain trying to get information out of the following C struct in a nice way when using ctypes:
struct Foo
{
unsigned int length;
char name[];
};
I wrote a little C function to get instance of the struct easily into python:
struct Foo *
put_name(char *name)
{
struct Foo *foo = malloc(sizeof(struct Foo) + strlen(name));
foo->length = strlen(name);
memcpy(foo->name, name, foo->length);
return(foo);
}
Now, how do I actually get the full contents of Foo.name in python? The only way I could think of that actually works is to create a dummy-struct type in order to get the length out and then use it to dynamically create a new sub-class of ctypes.Structure, then create an instance based on the address of what was returned. I think the following shows it pretty clearly:
class FOO(Structure):
_fields_ = [('length', c_uint), ('name', c_char * 0)]
liblib = cdll.LoadLibrary(’./_build/liblib.so’)
c_put_name = liblib.put_name
c_put_name.argtypes = [c_char_p]
c_put_name.restype = POINTER(FOO)
def put_name(str):
f = c_put_name(str)
K = type(’FOO%s’ % f.contents.length, (Structure,),
{’_fields_’ : [('length', c_uint), ('name', c_char * f.contents.length)]})
return K.from_address(addressof(f.contents))
I still think there ought to be some other way that ‘feels’ nicer. I mean the use of “short arrays” (declared as here with [], or zero size as supported by GCC, or the more portable array of size one) seems to be common enough to warrant some support from ctypes, right?
Any suggestions for improvements?