13.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. Unfortunately this only works on Windows. It does this by examining the stack after the function returns:

>>> 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)
>>>

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.

Python integers, strings and unicode strings are the only objects that can directly be used as parameters in these function calls.

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.