14.14.1.3 Calling functions
You can call these functions like any other Python callable. This
example uses the time()
function, which returns system time in
seconds since the Unix epoch, and the GetModuleHandleA()
function,
which returns a win32 module handle.
This example calls both functions with a NULL pointer (None
should
be used as the NULL pointer):
>>> print libc.time(None) # doctest: +SKIP 1150640792 >>> print hex(windll.kernel32.GetModuleHandleA(None)) # doctest: +WINDOWS 0x1d000000 >>>
ctypes
tries to protect you from calling functions with the wrong
number of arguments or the wrong calling convention. Unfortunately
this only works on Windows. It does this by examining the stack after
the function returns, so although an error is raised the function
has been called:
>>> windll.kernel32.GetModuleHandleA() # doctest: +WINDOWS Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Procedure probably called with not enough arguments (4 bytes missing) >>> windll.kernel32.GetModuleHandleA(0, 0) # doctest: +WINDOWS Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Procedure probably called with too many arguments (4 bytes in excess) >>>
The same exception is raised when you call an stdcall
function
with the cdecl
calling convention, or vice versa:
>>> cdll.kernel32.GetModuleHandleA(None) # doctest: +WINDOWS Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Procedure probably called with not enough arguments (4 bytes missing) >>> >>> windll.msvcrt.printf("spam") # doctest: +WINDOWS Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: Procedure probably called with too many arguments (4 bytes in excess) >>>
To find out the correct calling convention you have to look into the C header file or the documentation for the function you want to call.
On Windows, ctypes
uses win32 structured exception handling to
prevent crashes from general protection faults when functions are
called with invalid argument values:
>>> windll.kernel32.GetModuleHandleA(32) # doctest: +WINDOWS Traceback (most recent call last): File "<stdin>", line 1, in ? WindowsError: exception: access violation reading 0x00000020 >>>
There are, however, enough ways to crash Python with ctypes
, so
you should be careful anyway.
None
, integers, longs, byte strings and unicode strings are the
only native Python objects that can directly be used as parameters in
these function calls. None
is passed as a C NULL
pointer,
byte strings and unicode strings are passed as pointer to the memory
block that contains their data (char *
or wchar_t *
). Python
integers and Python longs are passed as the platforms default C
int
type, their value is masked to fit into the C type.
Before we move on calling functions with other parameter types, we
have to learn more about ctypes
data types.
See About this document... for information on suggesting changes.