How to malloc cvalues from python?

问题描述 投票:0回答:1

这个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 解决这种情况?

python c memory ctypes
1个回答
0
投票

使用以下模式分配结构数组:

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
© www.soinside.com 2019 - 2024. All rights reserved.