Как мне перевести обратный вызов typedef с именованными параметрами?

#python-3.x #ctypes

#python-3.x #ctypes

Вопрос:

Итак, я получаю строку заголовка, подобную этой:

 typedef PVOID   (WINAPI *GDIMARSHALLOC)(DWORD dwSize, __in LPVOID pGdiRef);
  

Как я могу поддерживать имена параметров / флаги без вызова прототипа?

Единственное, что я знаю, как сделать, это что-то вроде этого:

 GDIMARSHALLOC = POINTER(CALLBACK(PVOID, DWORD, LPVOID))
  

обратите внимание, что CALLBACK это пользовательское определение, подобное WINFUNCTYPE .

Комментарии:

1. В прототипе имена не имеют значения, только типы. Что у вас не работает?

2. Дело не столько в том, что не работает, сколько в том, что я могу сделать, чтобы даже получить предоставленные имена (я бы предпочел это для полноты картины), возможно ли это вообще или ctypes просто не имеют поддержки?

Ответ №1:

Вы можете указать paramflags при создании экземпляра прототипа CFUNCTYPE / WINFUNCTYPE, но не можете указать имена параметров, но я не понимаю, как это помогает при обратном вызове, поскольку это вызывалось бы вне вашего кода.

Смотрите нижнюю часть прототипов функций в ctypes документации для обсуждения paramflags.

Вот пример из этой документации:

 >>> from ctypes import c_int, WINFUNCTYPE, windll
>>> from ctypes.wintypes import HWND, LPCWSTR, UINT
>>> prototype = WINFUNCTYPE(c_int, HWND, LPCWSTR, LPCWSTR, UINT)
>>> paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", "Hello from ctypes"), (1, "flags", 0)
>>> MessageBox = prototype(("MessageBoxW", windll.user32), paramflags)
  

Внешняя функция MessageBox теперь может вызываться следующими способами:

 >>> MessageBox()
>>> MessageBox(text="Spam, spam, spam")
>>> MessageBox(flags=2, text="foo bar")
  

Комментарии:

1. Да, к сожалению, на самом деле это не ответ, но это хорошая информация, легко доступная для других… Но мне нужны парамфлаги, в основном поставляемые с самим прототипом, а не с экземпляром прототипа. И, кстати, небольшое замечание о плохой документации python, тип записи paramflag 3 (inout) не упоминается.

2. @Tcll Ну, это ответ. Ответ в том, что вы не можете сделать это с прототипом, только с экземпляром одного. Также в документах говорится, что это флаги параметров, которые можно комбинировать, поэтому 3 равно 1 2 или inout .

3. @Tcll Вы всегда можете прокомментировать прототип. В C экземпляры typedef также не должны совпадать с именами параметров в typedef, поэтому они в основном тоже похожи на комментарий. Обычно я все равно помещаю комментарий к прототипу C, который я оборачиваю, чтобы будущие пользователи могли судить, правильно ли он был обернут.

4. Достаточно справедливо, или doc-comment, что может быть лучше, если IDE поддерживает динамический __doc__ доступ. Спасибо, что помогли мне понять, я отвечу на это своим собственным механизмом, никто не сравнится со мной в этом. 🙂