我正在包装的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的子类。具有...