Function prototypes can be instantiated with a paramflags
tuple, which specifies whether each parameter in argtypes
is an input parameter (1), output parameter (2), or in-out parameter (3). Optionally, it can also specify a name and default value for each parameter, which allows the function to be called with keyword arguments. For example:
import ctypes
libm = ctypes.CDLL('libm.so.6')
pow_prototype = ctypes.CFUNCTYPE(
ctypes.c_double,
ctypes.c_double, ctypes.c_double,
use_errno=True)
pow_paramflags = ((1, 'x'), (1, 'y', 2)) # default to returning x**2
pow = pow_prototype(('pow', libm), pow_paramflags)
>>> pow(3)
9.0
>>> pow(3, 3)
27.0
>>> pow(x=3)
9.0
>>> pow(x=3, y=3)
27.0
>>> pow(y=3, x=3)
27.0
The parameter names and default values (if any) can be pulled directly from the annotated prototype. If a parameter flag isn’t specified it can be assumed to be handled as an input parameter. An output parameter or in-out parameter could be declared by annotating with a tuple (type, flag)
.
A function prototype also has a _flags_
value in addition to _argtypes_
and _restype_
. The supported flag values are
FUNCFLAG_STDCALL = 0x00 # Windows only
FUNCFLAG_CDECL = 0x01
FUNCFLAG_HRESULT = 0x02 # Windows only
FUNCFLAG_PYTHONAPI = 0x04
FUNCFLAG_USE_ERRNO = 0x08
FUNCFLAG_USE_LASTERROR = 0x10
The last two enable the use of ctypes.get_errno()
and ctypes.get_last_error()
. Generally scripts rely on the default function prototype of a CDLL
, WinDLL
, or PyDLL
instance to set these flags, or a prototype factory function such as CFUNCTYPE()
, WINFUNCTYPE()
, or PYFUNCTYPE()
. Maybe they could be supported in an annotated prototype as keyword-only parameters such as _stdcall_
, _cdecl_
, _hresult_
, _pythonapi_
, _use_errno_
, and _use_last_error_
. A function pointer also has an errcheck
attribute, which is a function that gets called just before returning. Maybe this could be supported as an _errcheck_
keyword-only parameter. If any flag is defined, it will override the _flags_
of the default prototype of a CDLL
instance. If a default _errcheck_
is defined, it will be the initial errcheck
value of the function pointer.