This C file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Foo {
char *s;
int i;
};
struct Bar {
struct Foo *f;
int n;
};
void func(struct Bar *b)
{
for(int i = 0; i < b->n; i++) {
printf("s:%s i:%i\n", b->f[i].s, b->f[i].i);
}
}
//int main()
//{
// struct Foo *f = malloc(sizeof(*f) * 2);
// f[0].s = strdup("asd");
// f[0].i = 1;
// f[1].s = strdup("qwe");
// f[1].i = 2;
// struct Bar *b = malloc(sizeof(*b));
// b->f = f;
// b->n = 2;
// func(b); // works as expected
//}
And corresponding Python:
import ctypes
clibrary = ctypes.CDLL('clibrary.so')
class Foo(ctypes.Structure):
_fields_ = [
('s', ctypes.c_char_p),
('i', ctypes.c_int32)
]
class Bar(ctypes.Structure):
_fields_ = [
('f', ctypes.POINTER(Foo)),
('n', ctypes.c_int32)
]
b = Bar()
# b.f = ctypes.Array(2)
b.f[0] = Foo(b'asd', 4)
b.f[1] = Foo(b'qwe', 5)
b.n = 2
clibrary.func(ctypes.byref(b))
gives:
ValueError: NULL pointer access
I know that the Bar.f
is just not-allocated pointer, and that's why I make allocations in test main()
(commented out). But how can I do allocations in python? I am using the Bar.f
as a dynamic array in func()
, because I don't know the size, or how many Foos will I need in that array. How to tackle this scenario with ctypes?