这个C文件:
#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
//}
和对应的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))
给:
ValueError: NULL pointer access
我知道
Bar.f
只是未分配的指针,这就是为什么我在测试中进行分配main()
(注释掉)。但是我怎样才能在 python 中进行分配呢?我在 Bar.f
中使用 func()
作为动态数组,因为我不知道大小,也不知道该数组中需要多少个 Foos。如何使用 ctypes 解决这种情况?
使用以下模式分配结构数组:
array_n = (Structure * array_size)()
Structure * array_size
是一个 type 并且用 ()
调用它使它成为一个 instance:
>>> Foo * 2 # sized array type
<class '__main__.Foo_Array_2'>
>>> (Foo * 2)() # instance of sized array
<__main__.Foo_Array_2 object at 0x000001F57FF4F5D0>
所以对代码做如下改动:
b.f = (Foo * 2)()
修改后效果如预期:
s:asd i:4
s:qwe i:5