Представьте, что есть какой-то интерфейс C с такими операциями (на практике я имею в виду webrtc vad API):
Код: Выделить всё
Handler* create();
int process(Handler*);
void free(Handler*);
Теперь экзотический вопрос. Можно ли представить этот шаблон как класс, производный от ctypes.c_void_p?
- В целом правильно ли производить производный от ctypes.c_void_p?
- Есть ли какие-либо ограничения для конструктора такого производного класса? Будет ли конструктор использоваться ctypes для создания маршаллированных возвращаемых дескрипторов?
- Правильно ли изменять self.value в производном классе __init__?
- Как ctypes создает объект HandlerPointer, будет ли он вызывать __init__ и будет ли это препятствовать его правильному функционированию?
- Вызывает ли ctypes правильно поддерживать/маршалировать c_void_p-argtypes/restypes, производные от c_void_p?
- Есть ли более естественный способ представления таких капсулоподобных объектов (указатель на возможно непрозрачную структуру вместе с деструктором функция)/API?
Код: Выделить всё
import os
import ctypes
class HandlerPointer(ctypes.c_void_p):
@staticmethod
def ffi(lib_path = os.path.abspath('mylib.so')):
lib = ctypes.CDLL(lib_path)
lib.create.argtypes = []
lib.create.restype = HandlerPointer
lib.process.argtypes = [HandlerPointer]
lib.process.restype = ctypes.c_int
lib.free.argtypes = [HandlerPointer]
lib.free.restype = None
return lib
def __init__(self):
super().__init__()
self.value = self.lib.create().value
def process(self):
return self.lib.process(self)
def __del__(self):
self.lib.free(self)
# can't do this var init inside the class as can't refer yet to HandlerPointer inside `.ffi()` if class not initialized yet
HandlerPointer.lib = HandlerPointer.ffi() # otherwise
Подробнее здесь: https://stackoverflow.com/questions/788 ... c-function