У меня есть библиотека C с несколькими типами данных, которые я завернул с Python и ctypes - работает очень хорошо! В CI есть следующий (схематический) код:
typedef struct type1_struct type1_t;
typedef struct type2_struct type2_t;
void some_function( type1_t *t1 , type2_t *t2) {
if (t2 == NULL) {
// Do whatever
} else {
//
}
}
Основная часть этого кода заключается в том, что some_function() может принимать значение NULL как значение для аргумента t2. В Python типы type1_t и type2_t обертываются классами Type1 и Type2 с помощью метода from_param():
Class Type1:
def from_param(self):
return self.c_ptr
def call_some_func(self , arg2 = None):
# This fails when the python/ctypes tries to
# lookup the from_param() method and arg2 is None.
cfunc_some_function( self , arg2 )
lib_handle = ctypes.CDLL( lib )
cfunc_some_function = getattr( lib_handle , "some_function")
cfunc_some_function.argtypes = [Type1 , Type2]
Таким образом, функция cfunc_some_function инициализируется, чтобы взять экземпляр Type1 и Type2 в качестве аргументов, тогда уровень ctypes вызывает методы from_param() двух входных аргументов; однако я бы хотел, чтобы метод call_some_func() класса Type1 принимал None для аргумента arg2, но затем ctypes пытается вызвать метод from_param() объекта None, что явно не удается.
Итак, я думаю, мой вопрос: возможно ли получить код вызова функции ctypes, чтобы просто передать NULL, когда он получает входной аргумент None?
Йоаким
Метод from_param()
должен быть методом класса, но вы определили его как метод экземпляра. Измените его на classmethod
и проверьте, является ли параметр None.
Что-то вроде (непроверено):
class Type1:
@classmethod
def from_param(cls, obj):
if obj is None:
return c_void_p()
else:
return obj.c_ptr
и то же самое для Type2.
Возможно, вы можете преобразовать None в Type2 перед вызовом:
cfunc_some_function( self , Type2(arg2) )
и Type2.from_param() возвращает правый объект для cfunc_some_function().
Type.method(obj)
иobj.method()
взаимозаменяемы, когдаobj
является экземпляромType
, но ctypes также может вызыватьType.method(obj)
когда obj другого типа, такого какNone
и вот с чем ты столкнулся.