ctypes当指向Python ctypes.Structure的指针被释放时,如何调用deallocator?

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

我正在包装的C库需要在C函数内部分配和破坏结构的内存,并且始终传递指针,而不是结构。

我具有使用ctypes.Structure方法的__del__的子类。在实例上调用del时,不会调用此方法,该实例是从C(Foo_init)中的函数返回的结构的指针。有趣的是,如果该实例不是指针,而是从其他C函数(del)返回的实际值,则在调用Foo_init_value时将调用它。

如何获得__del__方法来调用指向从C函数返回的结构的指针?

在Python中:

import ctypes
import gc
libfoo = ctypes.CDLL("libfoo.so")

class Foo(ctypes.Structure):
    _fields_ = [
        ('a', ctypes.c_int),
        ('b', ctypes.POINTER(ctypes.c_char)),
    ]
    def __del__(self):
        print('deleting')
        libfoo.Foo_destroy(self)

# Get a pointer to Foo
libfoo.Foo_init.restype = ctypes.POINTER(Foo)
libfoo.Foo_init.argtypes = None

# Get actual Foo, not pointer
libfoo.Foo_init_value.restype = Foo
libfoo.Foo_init_value.argtypes = None

libfoo.Foo_destroy.restype = ctypes.c_int
libfoo.Foo_destroy.argtypes = [ctypes.POINTER(Foo)]

# Get a pointer to Foo
foo = libfoo.Foo_init()
# Nothing is printed here:
del foo
# Nothing is printed here
gc.collect()
# Nothing is printed here
[f for f in gc.get_objects() if isinstance(f, Foo)]

# Get an actual Foo, not pointer
foo = libfoo.Foo_init_value()
# This works, prints 'deleting'
del foo

这是我琐碎的C库:

#include <stdlib.h>

typedef struct Foo {
    int a;
    char *b;
} Foo;

/* Allocate and return pointer to Foo */
/* __del__ does not work for this one */
Foo *Foo_init(void)
{
    Foo *foo = (Foo *) malloc(sizeof(Foo));
    if (!foo) {
        return NULL;
    }
    foo->a = 0;
    foo->b = NULL;
    return foo;
}

/* Allocate and return value of Foo, not a pointer*/
/* __del__ works on this */
Foo Foo_init_value(void)
{
    Foo *foo = Foo_init();
    return *foo;
}

int *Foo_destroy(Foo *foo)
{
    if (foo->b) {
         free(foo->b);
         foo->b = NULL;
    }
    return 0;
}

要编译:

gcc -c -Wall -Werror -fpic foo.c
gcc -shared -o libfoo.so foo.o

我正在包装的C库要求分配和破坏C函数内部结构的内存,并且始终传递指针而不是结构。我有一个ctypes的子类。具有...

python python-3.x ctypes
1个回答
0
投票
© www.soinside.com 2019 - 2024. All rights reserved.