#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__
доступ. Спасибо, что помогли мне понять, я отвечу на это своим собственным механизмом, никто не сравнится со мной в этом. 🙂