Я использую SWIG для создания привязок языка Python к моей библиотеке C. Мне удалось создать привязки и экспортировать структуры данных, но при использовании библиотеки мне приходится преодолевать некоторые трудности.
Например, заголовок C имеет следующие типы данных и прототипы функций:
struct MyStruct
{
/* fields */
}
struct MyStruct * MYSTRUCT_Alloc(void);
void MYSTRUCT_Free(struct MyStruct *);
struct MyStruct * MYSTRUCT_Clone(const struct MyStruct *);
int MYSTRUCT_Func1(const struct MyStruct *, const int);
/* and so on */
В моем файле интерфейса SWIG я экспортирую как функции, так и тип данных MyStruct. Предполагая, что мой модуль расширения Python называется foobar, я могу написать скрипт Python следующим образом:
#import foobar as fb
# The line below creates a Python class which is a wrapper to MyStruct. HOWEVER I cannot pass this class to a function like MYSTRUCT_Func1 until I have initialized it by calling MYSTRUCT_Alloc ...
ms = fb.MyStruct
# This will fail (throws a Python exception)
# ret = fb.MYSTRUCT_Func1(ms, 123)
# However this works
ms = fb.MYSTRUCT_Alloc()
ret = fb.MYSTRUCT_Func1(ms, 123)
Очень громоздко (и подвержено ошибкам) объявлять объект, а затем присваивать ему указатель перед его использованием. Есть ли лучший способ использования сгенерированных SWIG классов? Я думал об оболочке классов более высокого уровня (или создании подклассов сгенерированных SWIG классов), чтобы автоматически заботиться о создании и уничтожении объектов (а также о предоставлении некоторых ОЧЕВИДНЫХ функций-членов, таких как MYSTRUCT_Func1().
ОДНАКО, если я оберну/подклассифицирую сгенерированные SWIG классы, то я не уверен, что смогу передать новые классы функциям C API, которые ожидают указатель на структуру C. Я не могу напрямую изменять сгенерированные классы SWIG (или, по крайней мере, не должен) - по ОЧЕВИДНЫМ причинам.
Каков наилучший способ решить эту проблему? Более питонический способ создания/уничтожения объектов, в то же время имея возможность передавать указатели непосредственно на открытые функции C?