I am trying to implement this C structures in python using ctypes:
struct _rows {
int cols_count;
char *cols[];
}
struct _unit {
int rows_count;
struct _rows *rows;
}
int my_func(struct _unit *param);
Problem is that _rows.cols is a dynamically sized array of char pointer and _unit.rows is a dynamically sized array of _rows structure. How can I implement this using ctypes in python?
I was able to define a function that will return a _rows structure with variable number of char pointers:
def get_row(cols):
class Row(ctypes.Structure):
_fields_ = [("cols_count", ctypes.c_int),
("cols", ctypes.c_char_p * cols)
]
I don't know what to do nex, it's all a bit fuzzy and ctypes documentation isn't helping.
I'm making some assumptions about what the OP wants, and I'd love suggestions if there is an easier way to do this, but this is what I came up with:
import string
from ctypes import Structure,c_int,c_char_p,POINTER,cast,pointer,byref,CDLL
class Row(Structure):
_fields_ = [('cols_count', c_int),
('cols', POINTER(c_char_p))]
def __init__(self,cols):
self.cols_count = cols
# Allocate an array of character pointers
pc = (c_char_p * cols)()
self.cols = cast(pc,POINTER(c_char_p))
class Unit(Structure):
_fields_ = [('rows_count', c_int),
('rows',POINTER(Row))]
def __init__(self,rows,cols):
self.rows_count = rows
# Allocate an array of Row structures.
# This does NOT call __init__.
pr = (Row * rows)()
# Call init manually with the column size.
for r in pr:
r.__init__(cols)
self.rows = cast(pr,POINTER(Row))
unit = Unit(2,3)
# Stuff some strings ('aaaaa','bbbbb',etc.)
for i in xrange(unit.rows_count):
for j in xrange(unit.rows[i].cols_count):
unit.rows[i].cols[j] = string.ascii_lowercase[i*5+j]*5
dll = CDLL('test.dll')
dll.my_func(byref(unit))
#include <stdio.h>
struct _rows {
int cols_count;
char **cols;
};
struct _unit {
int rows_count;
struct _rows *rows;
};
__declspec(dllexport) int my_func(struct _unit *param)
{
int i,j;
for(i=0;i<param->rows_count;i++)
for(j=0;j<param->rows[i].cols_count;j++)
printf("%d,%d = %s\n",i,j,param->rows[i].cols[j]);
return 0;
}
Compiled with Visual Studio 2010.
test.dll: test.c
cl /W4 /LD test.c
0,0 = aaaaa
0,1 = bbbbb
0,2 = ccccc
1,0 = fffff
1,1 = ggggg
1,2 = hhhhh
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With