python: ctypes, вызывает ли argtypes конструкторы автоматически?

#python #ctypes

#python #ctypes

Вопрос:

У меня есть код, который работает, но я не знаю, почему он работает.

 str2payload = lib3.str2payload
str2payload.argtypes = [POINTER(mbuf_t), POINTER(c_char)]

# sbuf = ..
val = b"asdfasdfasdhfjkasgdfjasgdfhjasgdfjhasgdfjhasgdfgjh"
rmr_str2payload(sbuf, val)
  

И это работает так, как ожидалось. Здесь val — это просто объект bytes в python. Однако сигнатура функции говорит, что это должно быть POINTER(c_char) . Так что же выполняет волшебное преобразование?

кстати, причина, по которой я использую POINTER(c_char) , заключается в том, что здесь написано:https://docs.python.org/3.7/library/ctypes.html#ctypes.c_char_p

Ответ №1:

Из документации ctypes:

При вызове внешней функции каждый фактический аргумент передается методу класса from_param() элементов в кортеже argtypes, этот метод позволяет адаптировать фактический аргумент к объекту, который принимает внешняя функция. Например, элемент c_char_p в кортеже argtypes преобразует строку unicode, переданную в качестве аргумента, в байтовую строку, используя правила преобразования ctypes.

Новое: теперь в argtypes можно помещать элементы, которые не являются типами ctypes, но каждый элемент должен иметь метод from_param(), который возвращает значение, используемое в качестве аргумента (целое число, строка, экземпляр ctypes). Это позволяет определять адаптеры, которые могут адаптировать пользовательские объекты в качестве параметров функции.