gh-120313: amend documentation regarding `ctypes._CFuncPtr` (GH-120989)

improve docs
This commit is contained in:
Bénédikt Tran 2024-10-25 15:32:23 +02:00 committed by GitHub
parent cae853e3b4
commit 417c130ba5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 29 additions and 19 deletions

View File

@ -397,7 +397,7 @@ as calling functions with a fixed number of parameters. On some platforms, and i
particular ARM64 for Apple Platforms, the calling convention for variadic functions particular ARM64 for Apple Platforms, the calling convention for variadic functions
is different than that for regular functions. is different than that for regular functions.
On those platforms it is required to specify the :attr:`~_FuncPtr.argtypes` On those platforms it is required to specify the :attr:`~_CFuncPtr.argtypes`
attribute for the regular, non-variadic, function arguments: attribute for the regular, non-variadic, function arguments:
.. code-block:: python3 .. code-block:: python3
@ -405,7 +405,7 @@ attribute for the regular, non-variadic, function arguments:
libc.printf.argtypes = [ctypes.c_char_p] libc.printf.argtypes = [ctypes.c_char_p]
Because specifying the attribute does not inhibit portability it is advised to always Because specifying the attribute does not inhibit portability it is advised to always
specify :attr:`~_FuncPtr.argtypes` for all variadic functions. specify :attr:`~_CFuncPtr.argtypes` for all variadic functions.
.. _ctypes-calling-functions-with-own-custom-data-types: .. _ctypes-calling-functions-with-own-custom-data-types:
@ -440,9 +440,9 @@ Specifying the required argument types (function prototypes)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
It is possible to specify the required argument types of functions exported from It is possible to specify the required argument types of functions exported from
DLLs by setting the :attr:`~_FuncPtr.argtypes` attribute. DLLs by setting the :attr:`~_CFuncPtr.argtypes` attribute.
:attr:`~_FuncPtr.argtypes` must be a sequence of C data types (the :func:`!printf` function is :attr:`~_CFuncPtr.argtypes` must be a sequence of C data types (the :func:`!printf` function is
probably not a good example here, because it takes a variable number and probably not a good example here, because it takes a variable number and
different types of parameters depending on the format string, on the other hand different types of parameters depending on the format string, on the other hand
this is quite handy to experiment with this feature):: this is quite handy to experiment with this feature)::
@ -467,7 +467,7 @@ prototype for a C function), and tries to convert the arguments to valid types::
If you have defined your own classes which you pass to function calls, you have If you have defined your own classes which you pass to function calls, you have
to implement a :meth:`~_CData.from_param` class method for them to be able to use them to implement a :meth:`~_CData.from_param` class method for them to be able to use them
in the :attr:`~_FuncPtr.argtypes` sequence. The :meth:`~_CData.from_param` class method receives in the :attr:`~_CFuncPtr.argtypes` sequence. The :meth:`~_CData.from_param` class method receives
the Python object passed to the function call, it should do a typecheck or the Python object passed to the function call, it should do a typecheck or
whatever is needed to make sure this object is acceptable, and then return the whatever is needed to make sure this object is acceptable, and then return the
object itself, its :attr:`!_as_parameter_` attribute, or whatever you want to object itself, its :attr:`!_as_parameter_` attribute, or whatever you want to
@ -490,7 +490,7 @@ Return types
By default functions are assumed to return the C :c:expr:`int` type. Other By default functions are assumed to return the C :c:expr:`int` type. Other
return types can be specified by setting the :attr:`~_FuncPtr.restype` attribute of the return types can be specified by setting the :attr:`~_CFuncPtr.restype` attribute of the
function object. function object.
The C prototype of :c:func:`time` is ``time_t time(time_t *)``. Because :c:type:`time_t` The C prototype of :c:func:`time` is ``time_t time(time_t *)``. Because :c:type:`time_t`
@ -499,7 +499,7 @@ specify the :attr:`!restype` attribute::
>>> libc.time.restype = c_time_t >>> libc.time.restype = c_time_t
The argument types can be specified using :attr:`~_FuncPtr.argtypes`:: The argument types can be specified using :attr:`~_CFuncPtr.argtypes`::
>>> libc.time.argtypes = (POINTER(c_time_t),) >>> libc.time.argtypes = (POINTER(c_time_t),)
@ -522,7 +522,7 @@ a string pointer and a char, and returns a pointer to a string::
>>> >>>
If you want to avoid the :func:`ord("x") <ord>` calls above, you can set the If you want to avoid the :func:`ord("x") <ord>` calls above, you can set the
:attr:`~_FuncPtr.argtypes` attribute, and the second argument will be converted from a :attr:`~_CFuncPtr.argtypes` attribute, and the second argument will be converted from a
single character Python bytes object into a C char: single character Python bytes object into a C char:
.. doctest:: .. doctest::
@ -541,7 +541,7 @@ single character Python bytes object into a C char:
>>> >>>
You can also use a callable Python object (a function or a class for example) as You can also use a callable Python object (a function or a class for example) as
the :attr:`~_FuncPtr.restype` attribute, if the foreign function returns an integer. The the :attr:`~_CFuncPtr.restype` attribute, if the foreign function returns an integer. The
callable will be called with the *integer* the C function returns, and the callable will be called with the *integer* the C function returns, and the
result of this call will be used as the result of your function call. This is result of this call will be used as the result of your function call. This is
useful to check for error return values and automatically raise an exception:: useful to check for error return values and automatically raise an exception::
@ -569,7 +569,7 @@ get the string representation of an error code, and *returns* an exception.
:func:`GetLastError` to retrieve it. :func:`GetLastError` to retrieve it.
Please note that a much more powerful error checking mechanism is available Please note that a much more powerful error checking mechanism is available
through the :attr:`~_FuncPtr.errcheck` attribute; through the :attr:`~_CFuncPtr.errcheck` attribute;
see the reference manual for details. see the reference manual for details.
@ -877,7 +877,7 @@ Type conversions
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
Usually, ctypes does strict type checking. This means, if you have Usually, ctypes does strict type checking. This means, if you have
``POINTER(c_int)`` in the :attr:`~_FuncPtr.argtypes` list of a function or as the type of ``POINTER(c_int)`` in the :attr:`~_CFuncPtr.argtypes` list of a function or as the type of
a member field in a structure definition, only instances of exactly the same a member field in a structure definition, only instances of exactly the same
type are accepted. There are some exceptions to this rule, where ctypes accepts type are accepted. There are some exceptions to this rule, where ctypes accepts
other objects. For example, you can pass compatible array instances instead of other objects. For example, you can pass compatible array instances instead of
@ -898,7 +898,7 @@ pointer types. So, for ``POINTER(c_int)``, ctypes accepts an array of c_int::
>>> >>>
In addition, if a function argument is explicitly declared to be a pointer type In addition, if a function argument is explicitly declared to be a pointer type
(such as ``POINTER(c_int)``) in :attr:`~_FuncPtr.argtypes`, an object of the pointed (such as ``POINTER(c_int)``) in :attr:`~_CFuncPtr.argtypes`, an object of the pointed
type (``c_int`` in this case) can be passed to the function. ctypes will apply type (``c_int`` in this case) can be passed to the function. ctypes will apply
the required :func:`byref` conversion in this case automatically. the required :func:`byref` conversion in this case automatically.
@ -1627,10 +1627,20 @@ As explained in the previous section, foreign functions can be accessed as
attributes of loaded shared libraries. The function objects created in this way attributes of loaded shared libraries. The function objects created in this way
by default accept any number of arguments, accept any ctypes data instances as by default accept any number of arguments, accept any ctypes data instances as
arguments, and return the default result type specified by the library loader. arguments, and return the default result type specified by the library loader.
They are instances of a private class:
They are instances of a private local class :class:`!_FuncPtr` (not exposed
in :mod:`!ctypes`) which inherits from the private :class:`_CFuncPtr` class:
.. class:: _FuncPtr .. doctest::
>>> import ctypes
>>> lib = ctypes.CDLL(None)
>>> issubclass(lib._FuncPtr, ctypes._CFuncPtr)
True
>>> lib._FuncPtr is ctypes._CFuncPtr
False
.. class:: _CFuncPtr
Base class for C callable foreign functions. Base class for C callable foreign functions.
@ -1796,7 +1806,7 @@ different ways, depending on the type and number of the parameters in the call:
The optional *paramflags* parameter creates foreign function wrappers with much The optional *paramflags* parameter creates foreign function wrappers with much
more functionality than the features described above. more functionality than the features described above.
*paramflags* must be a tuple of the same length as :attr:`~_FuncPtr.argtypes`. *paramflags* must be a tuple of the same length as :attr:`~_CFuncPtr.argtypes`.
Each item in this tuple contains further information about a parameter, it must Each item in this tuple contains further information about a parameter, it must
be a tuple containing one, two, or three items. be a tuple containing one, two, or three items.
@ -1867,7 +1877,7 @@ value if there is a single one, or a tuple containing the output parameter
values when there are more than one, so the GetWindowRect function now returns a values when there are more than one, so the GetWindowRect function now returns a
RECT instance, when called. RECT instance, when called.
Output parameters can be combined with the :attr:`~_FuncPtr.errcheck` protocol to do Output parameters can be combined with the :attr:`~_CFuncPtr.errcheck` protocol to do
further output processing and error checking. The win32 ``GetWindowRect`` api further output processing and error checking. The win32 ``GetWindowRect`` api
function returns a ``BOOL`` to signal success or failure, so this function could function returns a ``BOOL`` to signal success or failure, so this function could
do the error checking, and raises an exception when the api call failed:: do the error checking, and raises an exception when the api call failed::
@ -1880,7 +1890,7 @@ do the error checking, and raises an exception when the api call failed::
>>> GetWindowRect.errcheck = errcheck >>> GetWindowRect.errcheck = errcheck
>>> >>>
If the :attr:`~_FuncPtr.errcheck` function returns the argument tuple it receives If the :attr:`~_CFuncPtr.errcheck` function returns the argument tuple it receives
unchanged, :mod:`ctypes` continues the normal processing it does on the output unchanged, :mod:`ctypes` continues the normal processing it does on the output
parameters. If you want to return a tuple of window coordinates instead of a parameters. If you want to return a tuple of window coordinates instead of a
``RECT`` instance, you can retrieve the fields in the function and return them ``RECT`` instance, you can retrieve the fields in the function and return them
@ -2180,7 +2190,7 @@ Data types
This method adapts *obj* to a ctypes type. It is called with the actual This method adapts *obj* to a ctypes type. It is called with the actual
object used in a foreign function call when the type is present in the object used in a foreign function call when the type is present in the
foreign function's :attr:`~_FuncPtr.argtypes` tuple; foreign function's :attr:`~_CFuncPtr.argtypes` tuple;
it must return an object that can be used as a function call parameter. it must return an object that can be used as a function call parameter.
All ctypes data types have a default implementation of this classmethod All ctypes data types have a default implementation of this classmethod
@ -2246,7 +2256,7 @@ Fundamental data types
Fundamental data types, when returned as foreign function call results, or, for Fundamental data types, when returned as foreign function call results, or, for
example, by retrieving structure field members or array items, are transparently example, by retrieving structure field members or array items, are transparently
converted to native Python types. In other words, if a foreign function has a converted to native Python types. In other words, if a foreign function has a
:attr:`~_FuncPtr.restype` of :class:`c_char_p`, you will always receive a Python bytes :attr:`~_CFuncPtr.restype` of :class:`c_char_p`, you will always receive a Python bytes
object, *not* a :class:`c_char_p` instance. object, *not* a :class:`c_char_p` instance.
.. XXX above is false, it actually returns a Unicode string .. XXX above is false, it actually returns a Unicode string