ctypes

ctypes is a foreign function library for Python. It provides C compatibledata types, and allows calling functions in DLLs or shared libraries. It can beused to wrap these libraries in pure Python.

15.17.1. ctypes tutorial

Note: The code samples in this tutorial use doctest to make sure thatthey actually work. Since some code samples behave differently under Linux,Windows, or Mac OS X, they contain doctest directives in comments.

Note: Some code samples reference the ctypes c_int type. This type isan alias for the c_long type on 32-bit systems. So, you should not beconfused if c_long is printed if you would expect c_int —they are actually the same type.

15.17.1.2. Accessing functions from loaded dlls

Functions are accessed as attributes of dll objects:

>>>
>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print windll.kernel32.GetModuleHandleA 
<_FuncPtr object at 0x...>
>>> print windll.kernel32.MyOwnFunction 
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>

Note that win32 system dlls like kernel32 and user32 often export ANSIas well as UNICODE versions of a function. The UNICODE version is exported withan W appended to the name, while the ANSI version is exported with an Aappended to the name. The win32 GetModuleHandle function, which returns amodule handle for a given module name, has the following C prototype, and amacro is used to expose one of them as GetModuleHandle depending on whetherUNICODE is defined or not:

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);

windll does not try to select one of them by magic, you must access theversion you need by specifying GetModuleHandleA or GetModuleHandleWexplicitly, and then call it with strings or unicode stringsrespectively.

Sometimes, dlls export functions with names which aren’t valid Pythonidentifiers, like "??2@YAPAXI@Z". In this case you have to usegetattr() to retrieve the function:

>>>
>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") 
<_FuncPtr object at 0x...>
>>>

On Windows, some dlls export functions not by name but by ordinal. Thesefunctions can be accessed by indexing the dll object with the ordinal number:

>>>
>>> cdll.kernel32[1] 
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0] 
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>

15.17.1.3. Calling functions

You can call these functions like any other Python callable. This example usesthe time() function, which returns system time in seconds since the Unixepoch, and the GetModuleHandleA() function, which returns a win32 modulehandle.

This example calls both functions with a NULL pointer (None should be usedas the NULL pointer):

>>>
>>> print libc.time(None) 
1150640792
>>> print hex(windll.kernel32.GetModuleHandleA(None)) 
0x1d000000
>>>

ctypes tries to protect you from calling functions with the wrong numberof arguments or the wrong calling convention. Unfortunately this only works onWindows. It does this by examining the stack after the function returns, soalthough an error is raised the function has been called:

>>>
>>> windll.kernel32.GetModuleHandleA() 
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) 
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 thecdecl calling convention, or vice versa:

>>>
>>> cdll.kernel32.GetModuleHandleA(None) 
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") 
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 headerfile or the documentation for the function you want to call.

On Windows, ctypes uses win32 structured exception handling to preventcrashes from general protection faults when functions are called with invalidargument values:

>>>
>>> windll.kernel32.GetModuleHandleA(32) 
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 youshould be careful anyway.

None, integers, longs, byte strings and unicode strings are the only nativePython 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 arepassed as pointer to the memory block that contains their data (char *or wchar_t *). Python integers and Python longs are passed as theplatforms default C int type, their value is masked to fit into the Ctype.

Before we move on calling functions with other parameter types, we have to learnmore about ctypes data types.

15.17.1.4. Fundamental data types

ctypes defines a number of primitive C compatible data types :

ctypes typeC typePython type
c_bool_Boolbool (1)
c_charchar1-character string
c_wcharwchar_t1-character unicode string
c_bytecharint/long
c_ubyteunsigned charint/long
c_shortshortint/long
c_ushortunsigned shortint/long
c_intintint/long
c_uintunsigned intint/long
c_longlongint/long
c_ulongunsigned longint/long
c_longlong__int64 or long longint/long
c_ulonglongunsigned __int64 orunsigned long longint/long
c_floatfloatfloat
c_doubledoublefloat
c_longdoublelong doublefloat
c_char_pchar * (NUL terminated)string or None
c_wchar_pwchar_t * (NUL terminated)unicode or None
c_void_pvoid *int/long or None
  1. The constructor accepts any object with a truth value.

All these types can be created by calling them with an optional initializer ofthe correct type and value:

>>>
>>> c_int()
c_long(0)
>>> c_char_p("Hello, World")
c_char_p('Hello, World')
>>> c_ushort(-3)
c_ushort(65533)
>>>

Since these types are mutable, their value can also be changed afterwards:

>>>
>>> i = c_int(42)
>>> print i
c_long(42)
>>> print i.value
42
>>> i.value = -99
>>> print i.value
-99
>>>

Assigning a new value to instances of the pointer types c_char_p,c_wchar_p, and c_void_p changes the memory location theypoint to, not the contents of the memory block (of course not, because Pythonstrings are immutable):

>>>
>>> s = "Hello, World"
>>> c_s = c_char_p(s)
>>> print c_s
c_char_p('Hello, World')
>>> c_s.value = "Hi, there"
>>> print c_s
c_char_p('Hi, there')
>>> print s                 # first string is unchanged
Hello, World
>>>

You should be careful, however, not to pass them to functions expecting pointersto mutable memory. If you need mutable memory blocks, ctypes has acreate_string_buffer() function which creates these in various ways. Thecurrent memory block contents can be accessed (or changed) with the rawproperty; if you want to access it as NUL terminated string, use the valueproperty:

>>>
>>> from ctypes import *
>>> p = create_string_buffer(3)      # create a 3 byte buffer, initialized to NUL bytes
>>> print sizeof(p), repr(p.raw)
3 '\x00\x00\x00'
>>> p = create_string_buffer("Hello")      # create a buffer containing a NUL terminated string
>>> print sizeof(p), repr(p.raw)
6 'Hello\x00'
>>> print repr(p.value)
'Hello'
>>> p = create_string_buffer("Hello", 10)  # create a 10 byte buffer
>>> print sizeof(p), repr(p.raw)
10 'Hello\x00\x00\x00\x00\x00'
>>> p.value = "Hi"
>>> print sizeof(p), repr(p.raw)
10 'Hi\x00lo\x00\x00\x00\x00\x00'
>>>

The create_string_buffer() function replaces the c_buffer() function(which is still available as an alias), as well as the c_string() functionfrom earlier ctypes releases. To create a mutable memory block containingunicode characters of the C type wchar_t use thecreate_unicode_buffer() function.

15.17.1.5. Calling functions, continued

Note that printf prints to the real standard output channel, not tosys.stdout, so these examples will only work at the console prompt, notfrom within IDLE or PythonWin:

>>>
>>> printf = libc.printf
>>> printf("Hello, %s\n", "World!")
Hello, World!
14
>>> printf("Hello, %S\n", u"World!")
Hello, World!
14
>>> printf("%d bottles of beer\n", 42)
42 bottles of beer
19
>>> printf("%f bottles of beer\n", 42.5)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: Don't know how to convert parameter 2
>>>

As has been mentioned before, all Python types except integers, strings, andunicode strings have to be wrapped in their corresponding ctypes type, sothat they can be converted to the required C data type:

>>>
>>> printf("An int %d, a double %f\n", 1234, c_double(3.14))
An int 1234, a double 3.140000
31
>>>

15.17.1.6. Calling functions with your own custom data types

You can also customize ctypes argument conversion to allow instances ofyour own classes be used as function arguments. ctypes looks for an_as_parameter_ attribute and uses this as the function argument. Ofcourse, it must be one of integer, string, or unicode:

>>>
>>> class Bottles(object):
...     def __init__(self, number):
...         self._as_parameter_ = number
...
>>> bottles = Bottles(42)
>>> printf("%d bottles of beer\n", bottles)
42 bottles of beer
19
>>>

If you don’t want to store the instance’s data in the _as_parameter_instance variable, you could define a property() which makes the dataavailable.

15.17.1.7. Specifying the required argument types (function prototypes)

It is possible to specify the required argument types of functions exported fromDLLs by setting the argtypes attribute.

argtypes must be a sequence of C data types (the printf function isprobably not a good example here, because it takes a variable number anddifferent types of parameters depending on the format string, on the other handthis is quite handy to experiment with this feature):

>>>
>>> printf.argtypes = [c_char_p, c_char_p, c_int, c_double]
>>> printf("String '%s', Int %d, Double %f\n", "Hi", 10, 2.2)
String 'Hi', Int 10, Double 2.200000
37
>>>

Specifying a format protects against incompatible argument types (just as aprototype for a C function), and tries to convert the arguments to valid types:

>>>
>>> printf("%d %d %d", 1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: wrong type
>>> printf("%s %d %f\n", "X", 2, 3)
X 2 3.000000
13
>>>

If you have defined your own classes which you pass to function calls, you haveto implement a from_param() class method for them to be able to use themin the argtypes sequence. The from_param() class method receivesthe Python object passed to the function call, it should do a typecheck orwhatever is needed to make sure this object is acceptable, and then return theobject itself, its _as_parameter_ attribute, or whatever you want topass as the C function argument in this case. Again, the result should be aninteger, string, unicode, a ctypes instance, or an object with an_as_parameter_ attribute.

15.17.1.8. Return types

By default functions are assumed to return the C int type. Otherreturn types can be specified by setting the restype attribute of thefunction object.

Here is a more advanced example, it uses the strchr function, which expectsa string pointer and a char, and returns a pointer to a string:

>>>
>>> strchr = libc.strchr
>>> strchr("abcdef", ord("d")) 
8059983
>>> strchr.restype = c_char_p # c_char_p is a pointer to a string
>>> strchr("abcdef", ord("d"))
'def'
>>> print strchr("abcdef", ord("x"))
None
>>>

If you want to avoid the ord("x") calls above, you can set theargtypes attribute, and the second argument will be converted from asingle character Python string into a C char:

>>>
>>> strchr.restype = c_char_p
>>> strchr.argtypes = [c_char_p, c_char]
>>> strchr("abcdef", "d")
'def'
>>> strchr("abcdef", "def")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: one character string expected
>>> print strchr("abcdef", "x")
None
>>> strchr("abcdef", "d")
'def'
>>>

You can also use a callable Python object (a function or a class for example) asthe restype attribute, if the foreign function returns an integer. Thecallable will be called with the integer the C function returns, and theresult of this call will be used as the result of your function call. This isuseful to check for error return values and automatically raise an exception:

>>>
>>> GetModuleHandle = windll.kernel32.GetModuleHandleA 
>>> def ValidHandle(value):
...     if value == 0:
...         raise WinError()
...     return value
...
>>>
>>> GetModuleHandle.restype = ValidHandle 
>>> GetModuleHandle(None) 
486539264
>>> GetModuleHandle("something silly") 
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in ValidHandle
WindowsError: [Errno 126] The specified module could not be found.
>>>

WinError is a function which will call Windows FormatMessage() api toget the string representation of an error code, and returns an exception.WinError takes an optional error code parameter, if no one is used, it callsGetLastError() to retrieve it.

Please note that a much more powerful error checking mechanism is availablethrough the errcheck attribute; see the reference manual for details.

15.17.1.9. Passing pointers (or: passing parameters by reference)

Sometimes a C api function expects a pointer to a data type as parameter,probably to write into the corresponding location, or if the data is too largeto be passed by value. This is also known as passing parameters by reference.

ctypes exports the byref() function which is used to passparameters by reference. The same effect can be achieved with thepointer() function, although pointer() does a lot more work since itconstructs a real pointer object, so it is faster to use byref() if youdon’t need the pointer object in Python itself:

>>>
>>> i = c_int()
>>> f = c_float()
>>> s = create_string_buffer('\000' * 32)
>>> print i.value, f.value, repr(s.value)
0 0.0 ''
>>> libc.sscanf("1 3.14 Hello", "%d %f %s",
...             byref(i), byref(f), s)
3
>>> print i.value, f.value, repr(s.value)
1 3.1400001049 'Hello'
>>>

15.17.1.10. Structures and unions

Structures and unions must derive from the Structure and Unionbase classes which are defined in the ctypes module. Each subclass mustdefine a _fields_ attribute. _fields_ must be a list of2-tuples, containing a field name and a field type.

The field type must be a ctypes type like c_int, or any otherderived ctypes type: structure, union, array, pointer.

Here is a simple example of a POINT structure, which contains two integers namedx and y, and also shows how to initialize a structure in the constructor:

>>>
>>> from ctypes import *
>>> class POINT(Structure):
...     _fields_ = [("x", c_int),
...                 ("y", c_int)]
...
>>> point = POINT(10, 20)
>>> print point.x, point.y
10 20
>>> point = POINT(y=5)
>>> print point.x, point.y
0 5
>>> POINT(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: too many initializers
>>>

You can, however, build much more complicated structures. A structure canitself contain other structures by using a structure as a field type.

Here is a RECT structure which contains two POINTs named upperleft andlowerright:

>>>
>>> class RECT(Structure):
...     _fields_ = [("upperleft", POINT),
...                 ("lowerright", POINT)]
...
>>> rc = RECT(point)
>>> print rc.upperleft.x, rc.upperleft.y
0 5
>>> print rc.lowerright.x, rc.lowerright.y
0 0
>>>

Nested structures can also be initialized in the constructor in several ways:

>>>
>>> r = RECT(POINT(1, 2), POINT(3, 4))
>>> r = RECT((1, 2), (3, 4))

Field descriptors can be retrieved from the class, they are usefulfor debugging because they can provide useful information:

>>>
>>> print POINT.x
<Field type=c_long, ofs=0, size=4>
>>> print POINT.y
<Field type=c_long, ofs=4, size=4>
>>>

Warning

ctypes does not support passing unions or structures with bit-fieldsto functions by value. While this may work on 32-bit x86, it’s notguaranteed by the library to work in the general case. Unions andstructures with bit-fields should always be passed to functions by pointer.

15.17.1.11. Structure/union alignment and byte order

By default, Structure and Union fields are aligned in the same way the Ccompiler does it. It is possible to override this behavior be specifying a_pack_ class attribute in the subclass definition. This must be set to apositive integer and specifies the maximum alignment for the fields. This iswhat #pragma pack(n) also does in MSVC.

ctypes uses the native byte order for Structures and Unions. To buildstructures with non-native byte order, you can use one of theBigEndianStructure, LittleEndianStructure,BigEndianUnion, and LittleEndianUnion base classes. Theseclasses cannot contain pointer fields.

15.17.1.12. Bit fields in structures and unions

It is possible to create structures and unions containing bit fields. Bit fieldsare only possible for integer fields, the bit width is specified as the thirditem in the _fields_ tuples:

>>>
>>> class Int(Structure):
...     _fields_ = [("first_16", c_int, 16),
...                 ("second_16", c_int, 16)]
...
>>> print Int.first_16
<Field type=c_long, ofs=0:0, bits=16>
>>> print Int.second_16
<Field type=c_long, ofs=0:16, bits=16>
>>>

15.17.1.13. Arrays

Arrays are sequences, containing a fixed number of instances of the same type.

The recommended way to create array types is by multiplying a data type with apositive integer:

TenPointsArrayType = POINT * 10

Here is an example of an somewhat artificial data type, a structure containing 4POINTs among other stuff:

>>>
>>> from ctypes import *
>>> class POINT(Structure):
...    _fields_ = ("x", c_int), ("y", c_int)
...
>>> class MyStruct(Structure):
...    _fields_ = [("a", c_int),
...                ("b", c_float),
...                ("point_array", POINT * 4)]
>>>
>>> print len(MyStruct().point_array)
4
>>>

Instances are created in the usual way, by calling the class:

arr = TenPointsArrayType()
for pt in arr:
    print pt.x, pt.y

The above code print a series of 0 0 lines, because the array contents isinitialized to zeros.

Initializers of the correct type can also be specified:

>>>
>>> from ctypes import *
>>> TenIntegers = c_int * 10
>>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>> print ii
<c_long_Array_10 object at 0x...>
>>> for i in ii: print i,
...
1 2 3 4 5 6 7 8 9 10
>>>

15.17.1.14. Pointers

Pointer instances are created by calling the pointer() function on actypes type:

>>>
>>> from ctypes import *
>>> i = c_int(42)
>>> pi = pointer(i)
>>>

Pointer instances have a contents attribute which returns the object towhich the pointer points, the i object above:

>>>
>>> pi.contents
c_long(42)
>>>

Note that ctypes does not have OOR (original object return), it constructs anew, equivalent object each time you retrieve an attribute:

>>>
>>> pi.contents is i
False
>>> pi.contents is pi.contents
False
>>>

Assigning another c_int instance to the pointer’s contents attributewould cause the pointer to point to the memory location where this is stored:

>>>
>>> i = c_int(99)
>>> pi.contents = i
>>> pi.contents
c_long(99)
>>>

Pointer instances can also be indexed with integers:

>>>
>>> pi[0]
99
>>>

Assigning to an integer index changes the pointed to value:

>>>
>>> print i
c_long(99)
>>> pi[0] = 22
>>> print i
c_long(22)
>>>

It is also possible to use indexes different from 0, but you must know whatyou’re doing, just as in C: You can access or change arbitrary memory locations.Generally you only use this feature if you receive a pointer from a C function,and you know that the pointer actually points to an array instead of a singleitem.

Behind the scenes, the pointer() function does more than simply createpointer instances, it has to create pointer types first. This is done withthe POINTER() function, which accepts any ctypes type, and returnsa new type:

>>>
>>> PI = POINTER(c_int)
>>> PI
<class 'ctypes.LP_c_long'>
>>> PI(42)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: expected c_long instead of int
>>> PI(c_int(42))
<ctypes.LP_c_long object at 0x...>
>>>

Calling the pointer type without an argument creates a NULL pointer.NULL pointers have a False boolean value:

>>>
>>> null_ptr = POINTER(c_int)()
>>> print bool(null_ptr)
False
>>>

ctypes checks for NULL when dereferencing pointers (but dereferencinginvalid non-NULL pointers would crash Python):

>>>
>>> null_ptr[0]
Traceback (most recent call last):
    ....
ValueError: NULL pointer access
>>>

>>> null_ptr[0] = 1234
Traceback (most recent call last):
    ....
ValueError: NULL pointer access
>>>

15.17.1.15. Type conversions

Usually, ctypes does strict type checking. This means, if you havePOINTER(c_int) in the argtypes list of a function or as the type ofa member field in a structure definition, only instances of exactly the sametype are accepted. There are some exceptions to this rule, where ctypes acceptsother objects. For example, you can pass compatible array instances instead ofpointer types. So, for POINTER(c_int), ctypes accepts an array of c_int:

>>>
>>> class Bar(Structure):
...     _fields_ = [("count", c_int), ("values", POINTER(c_int))]
...
>>> bar = Bar()
>>> bar.values = (c_int * 3)(1, 2, 3)
>>> bar.count = 3
>>> for i in range(bar.count):
...     print bar.values[i]
...
1
2
3
>>>

In addition, if a function argument is explicitly declared to be a pointer type(such as POINTER(c_int)) in argtypes, an object of the pointedtype (c_int in this case) can be passed to the function. ctypes will applythe required byref() conversion in this case automatically.

To set a POINTER type field to NULL, you can assign None:

>>>
>>> bar.values = None
>>>

Sometimes you have instances of incompatible types. In C, you can cast one typeinto another type. ctypes provides a cast() function which can beused in the same way. The Bar structure defined above acceptsPOINTER(c_int) pointers or c_int arrays for its values field,but not instances of other types:

>>>
>>> bar.values = (c_byte * 4)()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance
>>>

For these cases, the cast() function is handy.

The cast() function can be used to cast a ctypes instance into a pointerto a different ctypes data type. cast() takes two parameters, a ctypesobject that is or can be converted to a pointer of some kind, and a ctypespointer type. It returns an instance of the second argument, which referencesthe same memory block as the first argument:

>>>
>>> a = (c_byte * 4)()
>>> cast(a, POINTER(c_int))
<ctypes.LP_c_long object at ...>
>>>

So, cast() can be used to assign to the values field of Bar thestructure:

>>>
>>> bar = Bar()
>>> bar.values = cast((c_byte * 4)(), POINTER(c_int))
>>> print bar.values[0]
0
>>>

15.17.1.16. Incomplete Types

Incomplete Types are structures, unions or arrays whose members are not yetspecified. In C, they are specified by forward declarations, which are definedlater:

struct cell; /* forward declaration */

struct cell {
    char *name;
    struct cell *next;
};

The straightforward translation into ctypes code would be this, but it does notwork:

>>>
>>> class cell(Structure):
...     _fields_ = [("name", c_char_p),
...                 ("next", POINTER(cell))]
...
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in cell
NameError: name 'cell' is not defined
>>>

because the new class cell is not available in the class statement itself.In ctypes, we can define the cell class and set the _fields_attribute later, after the class statement:

>>>
>>> from ctypes import *
>>> class cell(Structure):
...     pass
...
>>> cell._fields_ = [("name", c_char_p),
...                  ("next", POINTER(cell))]
>>>

Lets try it. We create two instances of cell, and let them point to eachother, and finally follow the pointer chain a few times:

>>>
>>> c1 = cell()
>>> c1.name = "foo"
>>> c2 = cell()
>>> c2.name = "bar"
>>> c1.next = pointer(c2)
>>> c2.next = pointer(c1)
>>> p = c1
>>> for i in range(8):
...     print p.name,
...     p = p.next[0]
...
foo bar foo bar foo bar foo bar
>>>

15.17.1.17. Callback functions

ctypes allows to create C callable function pointers from Python callables.These are sometimes called callback functions.

First, you must create a class for the callback function, the class knows thecalling convention, the return type, and the number and types of arguments thisfunction will receive.

The CFUNCTYPE factory function creates types for callback functions using thenormal cdecl calling convention, and, on Windows, the WINFUNCTYPE factoryfunction creates types for callback functions using the stdcall callingconvention.

Both of these factory functions are called with the result type as firstargument, and the callback functions expected argument types as the remainingarguments.

I will present an example here which uses the standard C library’s qsort()function, this is used to sort items with the help of a callback function.qsort() will be used to sort an array of integers:

>>>
>>> IntArray5 = c_int * 5
>>> ia = IntArray5(5, 1, 7, 33, 99)
>>> qsort = libc.qsort
>>> qsort.restype = None
>>>

qsort() must be called with a pointer to the data to sort, the number ofitems in the data array, the size of one item, and a pointer to the comparisonfunction, the callback. The callback will then be called with two pointers toitems, and it must return a negative integer if the first item is smaller thanthe second, a zero if they are equal, and a positive integer else.

So our callback function receives pointers to integers, and must return aninteger. First we create the type for the callback function:

>>>
>>> CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
>>>

For the first implementation of the callback function, we simply print thearguments we get, and return 0 (incremental development ;-):

>>>
>>> def py_cmp_func(a, b):
...     print "py_cmp_func", a, b
...     return 0
...
>>>

Create the C callable callback:

>>>
>>> cmp_func = CMPFUNC(py_cmp_func)
>>>

And we’re ready to go:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), cmp_func) 
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
>>>

We know how to access the contents of a pointer, so lets redefine our callback:

>>>
>>> def py_cmp_func(a, b):
...     print "py_cmp_func", a[0], b[0]
...     return 0
...
>>> cmp_func = CMPFUNC(py_cmp_func)
>>>

Here is what we get on Windows:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), cmp_func) 
py_cmp_func 7 1
py_cmp_func 33 1
py_cmp_func 99 1
py_cmp_func 5 1
py_cmp_func 7 5
py_cmp_func 33 5
py_cmp_func 99 5
py_cmp_func 7 99
py_cmp_func 33 99
py_cmp_func 7 33
>>>

It is funny to see that on linux the sort function seems to work much moreefficiently, it is doing less comparisons:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), cmp_func) 
py_cmp_func 5 1
py_cmp_func 33 99
py_cmp_func 7 33
py_cmp_func 5 7
py_cmp_func 1 7
>>>

Ah, we’re nearly done! The last step is to actually compare the two items andreturn a useful result:

>>>
>>> def py_cmp_func(a, b):
...     print "py_cmp_func", a[0], b[0]
...     return a[0] - b[0]
...
>>>

Final run on Windows:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) 
py_cmp_func 33 7
py_cmp_func 99 33
py_cmp_func 5 99
py_cmp_func 1 99
py_cmp_func 33 7
py_cmp_func 1 33
py_cmp_func 5 33
py_cmp_func 5 7
py_cmp_func 1 7
py_cmp_func 5 1
>>>

and on Linux:

>>>
>>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) 
py_cmp_func 5 1
py_cmp_func 33 99
py_cmp_func 7 33
py_cmp_func 1 7
py_cmp_func 5 7
>>>

It is quite interesting to see that the Windows qsort() function needsmore comparisons than the linux version!

As we can easily check, our array is sorted now:

>>>
>>> for i in ia: print i,
...
1 5 7 33 99
>>>

Important note for callback functions:

Make sure you keep references to CFUNCTYPE objects as long as they are used fromC code. ctypes doesn’t, and if you don’t, they may be garbage collected,crashing your program when a callback is made.

15.17.1.18. Accessing values exported from dlls

Some shared libraries not only export functions, they also export variables. Anexample in the Python library itself is the Py_OptimizeFlag, an integer setto 0, 1, or 2, depending on the -O or -OO flag given onstartup.

ctypes can access values like this with the in_dll() class methods ofthe type. pythonapi is a predefined symbol giving access to the Python Capi:

>>>
>>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag")
>>> print opt_flag
c_long(0)
>>>

If the interpreter would have been started with -O, the sample wouldhave printed c_long(1), or c_long(2) if -OO would have beenspecified.

An extended example which also demonstrates the use of pointers accesses thePyImport_FrozenModules pointer exported by Python.

Quoting the Python docs: This pointer is initialized to point to an array of“struct _frozen” records, terminated by one whose members are all NULL or zero.When a frozen module is imported, it is searched in this table. Third-party codecould play tricks with this to provide a dynamically created collection offrozen modules.

So manipulating this pointer could even prove useful. To restrict the examplesize, we show only how this table can be read with ctypes:

>>>
>>> from ctypes import *
>>>
>>> class struct_frozen(Structure):
...     _fields_ = [("name", c_char_p),
...                 ("code", POINTER(c_ubyte)),
...                 ("size", c_int)]
...
>>>

We have defined the struct _frozen data type, so we can get the pointer tothe table:

>>>
>>> FrozenTable = POINTER(struct_frozen)
>>> table = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules")
>>>

Since table is a pointer to the array of struct_frozen records, wecan iterate over it, but we just have to make sure that our loop terminates,because pointers have no size. Sooner or later it would probably crash with anaccess violation or whatever, so it’s better to break out of the loop when wehit the NULL entry:

>>>
>>> for item in table:
...    print item.name, item.size
...    if item.name is None:
...        break
...
__hello__ 104
__phello__ -104
__phello__.spam 104
None 0
>>>

The fact that standard Python has a frozen module and a frozen package(indicated by the negative size member) is not well known, it is only used fortesting. Try it out with import __hello__ for example.

15.17.1.19. Surprises

There are some edge cases in ctypes where you might expect somethingother than what actually happens.

Consider the following example:

>>>
>>> from ctypes import *
>>> class POINT(Structure):
...     _fields_ = ("x", c_int), ("y", c_int)
...
>>> class RECT(Structure):
...     _fields_ = ("a", POINT), ("b", POINT)
...
>>> p1 = POINT(1, 2)
>>> p2 = POINT(3, 4)
>>> rc = RECT(p1, p2)
>>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
1 2 3 4
>>> # now swap the two points
>>> rc.a, rc.b = rc.b, rc.a
>>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
3 4 3 4
>>>

Hm. We certainly expected the last statement to print 3 4 1 2. Whathappened? Here are the steps of the rc.a, rc.b = rc.b, rc.a line above:

>>>
>>> temp0, temp1 = rc.b, rc.a
>>> rc.a = temp0
>>> rc.b = temp1
>>>

Note that temp0 and temp1 are objects still using the internal buffer ofthe rc object above. So executing rc.a = temp0 copies the buffercontents of temp0 into rc ‘s buffer. This, in turn, changes thecontents of temp1. So, the last assignment rc.b = temp1, doesn’t havethe expected effect.

Keep in mind that retrieving sub-objects from Structure, Unions, and Arraysdoesn’t copy the sub-object, instead it retrieves a wrapper object accessingthe root-object’s underlying buffer.

Another example that may behave different from what one would expect is this:

>>>
>>> s = c_char_p()
>>> s.value = "abc def ghi"
>>> s.value
'abc def ghi'
>>> s.value is s.value
False
>>>

Why is it printing False? ctypes instances are objects containing a memoryblock plus some descriptors accessing the contents of the memory.Storing a Python object in the memory block does not store the object itself,instead the contents of the object is stored. Accessing the contents againconstructs a new Python object each time!

15.17.1.20. Variable-sized data types

ctypes provides some support for variable-sized arrays and structures.

The resize() function can be used to resize the memory buffer of anexisting ctypes object. The function takes the object as first argument, andthe requested size in bytes as the second argument. The memory block cannot bemade smaller than the natural memory block specified by the objects type, aValueError is raised if this is tried:

>>>
>>> short_array = (c_short * 4)()
>>> print sizeof(short_array)
8
>>> resize(short_array, 4)
Traceback (most recent call last):
    ...
ValueError: minimum size is 8
>>> resize(short_array, 32)
>>> sizeof(short_array)
32
>>> sizeof(type(short_array))
8
>>>

This is nice and fine, but how would one access the additional elementscontained in this array? Since the type still only knows about 4 elements, weget errors accessing other elements:

>>>
>>> short_array[:]
[0, 0, 0, 0]
>>> short_array[7]
Traceback (most recent call last):
    ...
IndexError: invalid index
>>>

Another way to use variable-sized data types with ctypes is to use thedynamic nature of Python, and (re-)define the data type after the required sizeis already known, on a case by case basis.

15.17.2. ctypes reference

15.17.2.1. Finding shared libraries

When programming in a compiled language, shared libraries are accessed whencompiling/linking a program, and when the program is run.

The purpose of the find_library() function is to locate a library in a waysimilar to what the compiler does (on platforms with several versions of ashared library the most recent should be loaded), while the ctypes libraryloaders act like when a program is run, and call the runtime loader directly.

The ctypes.util module provides a function which can help to determine thelibrary to load.

ctypes.util. find_library ( name )

Try to find a library and return a pathname. name is the library name withoutany prefix like lib, suffix like .so, .dylib or version number (thisis the form used for the posix linker option -l). If no library canbe found, returns None.

The exact functionality is system dependent.

On Linux, find_library() tries to run external programs(/sbin/ldconfig, gcc, and objdump) to find the library file. Itreturns the filename of the library file. Here are some examples:

>>>
>>> from ctypes.util import find_library
>>> find_library("m")
'libm.so.6'
>>> find_library("c")
'libc.so.6'
>>> find_library("bz2")
'libbz2.so.1.0'
>>>

On OS X, find_library() tries several predefined naming schemes and pathsto locate the library, and returns a full pathname if successful:

>>>
>>> from ctypes.util import find_library
>>> find_library("c")
'/usr/lib/libc.dylib'
>>> find_library("m")
'/usr/lib/libm.dylib'
>>> find_library("bz2")
'/usr/lib/libbz2.dylib'
>>> find_library("AGL")
'/System/Library/Frameworks/AGL.framework/AGL'
>>>

On Windows, find_library() searches along the system search path, andreturns the full pathname, but since there is no predefined naming scheme a calllike find_library("c") will fail and return None.

If wrapping a shared library with ctypes, it may be better to determinethe shared library name at development time, and hardcode that into the wrappermodule instead of using find_library() to locate the library at runtime.

15.17.2.2. Loading shared libraries

There are several ways to loaded shared libraries into the Python process. Oneway is to instantiate one of the following classes:

class ctypes. CDLL ( name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False )

Instances of this class represent loaded shared libraries. Functions in theselibraries use the standard C calling convention, and are assumed to returnint.

class ctypes. OleDLL ( name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False )

Windows only: Instances of this class represent loaded shared libraries,functions in these libraries use the stdcall calling convention, and areassumed to return the windows specific HRESULT code. HRESULTvalues contain information specifying whether the function call failed orsucceeded, together with additional error code. If the return value signals afailure, an WindowsError is automatically raised.

class ctypes. WinDLL ( name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False )

Windows only: Instances of this class represent loaded shared libraries,functions in these libraries use the stdcall calling convention, and areassumed to return int by default.

On Windows CE only the standard calling convention is used, for convenience theWinDLL and OleDLL use the standard calling convention on thisplatform.

The Python global interpreter lock is released before calling anyfunction exported by these libraries, and reacquired afterwards.

class ctypes. PyDLL ( name, mode=DEFAULT_MODE, handle=None )

Instances of this class behave like CDLL instances, except that thePython GIL is not released during the function call, and after the functionexecution the Python error flag is checked. If the error flag is set, a Pythonexception is raised.

Thus, this is only useful to call Python C api functions directly.

All these classes can be instantiated by calling them with at least oneargument, the pathname of the shared library. If you have an existing handle toan already loaded shared library, it can be passed as the handle namedparameter, otherwise the underlying platforms dlopen or LoadLibraryfunction is used to load the library into the process, and to get a handle toit.

The mode parameter can be used to specify how the library is loaded. Fordetails, consult the dlopen(3) manpage, on Windows, mode isignored.

The use_errno parameter, when set to True, enables a ctypes mechanism thatallows to access the system errno error number in a safe way.ctypes maintains a thread-local copy of the systems errnovariable; if you call foreign functions created with use_errno=True then theerrno value before the function call is swapped with the ctypes privatecopy, the same happens immediately after the function call.

The function ctypes.get_errno() returns the value of the ctypes privatecopy, and the function ctypes.set_errno() changes the ctypes private copyto a new value and returns the former value.

The use_last_error parameter, when set to True, enables the same mechanism forthe Windows error code which is managed by the GetLastError() andSetLastError() Windows API functions; ctypes.get_last_error() andctypes.set_last_error() are used to request and change the ctypes privatecopy of the windows error code.

New in version 2.6: The use_last_error and use_errno optional parameters were added.

ctypes. RTLD_GLOBAL

Flag to use as mode parameter. On platforms where this flag is not available,it is defined as the integer zero.

ctypes. RTLD_LOCAL

Flag to use as mode parameter. On platforms where this is not available, itis the same as RTLD_GLOBAL.

ctypes. DEFAULT_MODE

The default mode which is used to load shared libraries. On OSX 10.3, this isRTLD_GLOBAL, otherwise it is the same as RTLD_LOCAL.

Instances of these classes have no public methods, however __getattr__()and __getitem__() have special behavior: functions exported by the sharedlibrary can be accessed as attributes of by index. Please note that both__getattr__() and __getitem__() cache their result, so calling themrepeatedly returns the same object each time.

The following public attributes are available, their name starts with anunderscore to not clash with exported function names:

PyDLL. _handle

The system handle used to access the library.

PyDLL. _name

The name of the library passed in the constructor.

Shared libraries can also be loaded by using one of the prefabricated objects,which are instances of the LibraryLoader class, either by calling theLoadLibrary() method, or by retrieving the library as attribute of theloader instance.

class ctypes. LibraryLoader ( dlltype )

Class which loads shared libraries. dlltype should be one of theCDLL, PyDLL, WinDLL, or OleDLL types.

__getattr__() has special behavior: It allows to load a shared library byaccessing it as attribute of a library loader instance. The result is cached,so repeated attribute accesses return the same library each time.

LoadLibrary ( name )

Load a shared library into the process and return it. This method alwaysreturns a new instance of the library.

These prefabricated library loaders are available:

ctypes. cdll

Creates CDLL instances.

ctypes. windll

Windows only: Creates WinDLL instances.

ctypes. oledll

Windows only: Creates OleDLL instances.

ctypes. pydll

Creates PyDLL instances.

For accessing the C Python api directly, a ready-to-use Python shared libraryobject is available:

ctypes. pythonapi

An instance of PyDLL that exposes Python C API functions asattributes. Note that all these functions are assumed to return Cint, which is of course not always the truth, so you have to assignthe correct restype attribute to use these functions.

15.17.2.3. Foreign functions

As explained in the previous section, foreign functions can be accessed asattributes of loaded shared libraries. The function objects created in this wayby default accept any number of arguments, accept any ctypes data instances asarguments, and return the default result type specified by the library loader.They are instances of a private class:

class ctypes. _FuncPtr

Base class for C callable foreign functions.

Instances of foreign functions are also C compatible data types; theyrepresent C function pointers.

This behavior can be customized by assigning to special attributes of theforeign function object.

restype

Assign a ctypes type to specify the result type of the foreign function.Use None for void, a function not returning anything.

It is possible to assign a callable Python object that is not a ctypestype, in this case the function is assumed to return a C int, andthe callable will be called with this integer, allowing to do furtherprocessing or error checking. Using this is deprecated, for more flexiblepost processing or error checking use a ctypes data type asrestype and assign a callable to the errcheck attribute.

argtypes

Assign a tuple of ctypes types to specify the argument types that thefunction accepts. Functions using the stdcall calling convention canonly be called with the same number of arguments as the length of thistuple; functions using the C calling convention accept additional,unspecified arguments as well.

When a foreign function is called, each actual argument is passed to thefrom_param() class method of the items in the argtypestuple, this method allows to adapt the actual argument to an object thatthe foreign function accepts. For example, a c_char_p item inthe argtypes tuple will convert a unicode string passed asargument into an byte string using ctypes conversion rules.

New: It is now possible to put items in argtypes which are not ctypestypes, but each item must have a from_param() method which returns avalue usable as argument (integer, string, ctypes instance). This allowsto define adapters that can adapt custom objects as function parameters.

errcheck

Assign a Python function or another callable to this attribute. Thecallable will be called with three or more arguments:

callable ( result, func, arguments )

result is what the foreign function returns, as specified by therestype attribute.

func is the foreign function object itself, this allows to reuse thesame callable object to check or post process the results of severalfunctions.

arguments is a tuple containing the parameters originally passed tothe function call, this allows to specialize the behavior on thearguments used.

The object that this function returns will be returned from theforeign function call, but it can also check the result valueand raise an exception if the foreign function call failed.

exception ctypes. ArgumentError

This exception is raised when a foreign function call cannot convert one of thepassed arguments.

15.17.2.4. Function prototypes

Foreign functions can also be created by instantiating function prototypes.Function prototypes are similar to function prototypes in C; they describe afunction (return type, argument types, calling convention) without defining animplementation. The factory functions must be called with the desired resulttype and the argument types of the function.

ctypes. CFUNCTYPE ( restype, *argtypes, use_errno=False, use_last_error=False )

The returned function prototype creates functions that use the standard Ccalling convention. The function will release the GIL during the call. Ifuse_errno is set to True, the ctypes private copy of the systemerrno variable is exchanged with the real errno value beforeand after the call; use_last_error does the same for the Windows errorcode.

Changed in version 2.6: The optional use_errno and use_last_error parameters were added.

ctypes. WINFUNCTYPE ( restype, *argtypes, use_errno=False, use_last_error=False )

Windows only: The returned function prototype creates functions that use thestdcall calling convention, except on Windows CE whereWINFUNCTYPE() is the same as CFUNCTYPE(). The function willrelease the GIL during the call. use_errno and use_last_error have thesame meaning as above.

ctypes. PYFUNCTYPE ( restype, *argtypes )

The returned function prototype creates functions that use the Python callingconvention. The function will not release the GIL during the call.

Function prototypes created by these factory functions can be instantiated indifferent ways, depending on the type and number of the parameters in the call:

prototype ( address )

Returns a foreign function at the specified address which must be an integer.

prototype ( callable )

Create a C callable function (a callback function) from a Python callable.

prototype ( func_spec [, paramflags ] )

Returns a foreign function exported by a shared library. func_spec must be a2-tuple (name_or_ordinal, library). The first item is the name of theexported function as string, or the ordinal of the exported function as smallinteger. The second item is the shared library instance.

prototype ( vtbl_index, name [, paramflags [, iid ] ] )

Returns a foreign function that will call a COM method. vtbl_index is theindex into the virtual function table, a small non-negative integer. name isname of the COM method. iid is an optional pointer to the interface identifierwhich is used in extended error reporting.

COM methods use a special calling convention: They require a pointer to the COMinterface as first argument, in addition to those parameters that are specifiedin the argtypes tuple.

The optional paramflags parameter creates foreign function wrappers with muchmore functionality than the features described above.

paramflags must be a tuple of the same length as argtypes.

Each item in this tuple contains further information about a parameter, it mustbe a tuple containing one, two, or three items.

The first item is an integer containing a combination of directionflags for the parameter:

1
Specifies an input parameter to the function.
2
Output parameter. The foreign function fills in a value.
4
Input parameter which defaults to the integer zero.

The optional second item is the parameter name as string. If this is specified,the foreign function can be called with named parameters.

The optional third item is the default value for this parameter.

This example demonstrates how to wrap the Windows MessageBoxA function sothat it supports default parameters and named arguments. The C declaration fromthe windows header file is this:

WINUSERAPI int WINAPI
MessageBoxA(
    HWND hWnd ,
    LPCSTR lpText,
    LPCSTR lpCaption,
    UINT uType);

Here is the wrapping with ctypes:

>>>
>>> from ctypes import c_int, WINFUNCTYPE, windll
>>> from ctypes.wintypes import HWND, LPCSTR, UINT
>>> prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
>>> paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
>>> MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)
>>>

The MessageBox foreign function can now be called in these ways:

>>>
>>> MessageBox()
>>> MessageBox(text="Spam, spam, spam")
>>> MessageBox(flags=2, text="foo bar")
>>>

A second example demonstrates output parameters. The win32 GetWindowRectfunction retrieves the dimensions of a specified window by copying them intoRECT structure that the caller has to supply. Here is the C declaration:

WINUSERAPI BOOL WINAPI
GetWindowRect(
     HWND hWnd,
     LPRECT lpRect);

Here is the wrapping with ctypes:

>>>
>>> from ctypes import POINTER, WINFUNCTYPE, windll, WinError
>>> from ctypes.wintypes import BOOL, HWND, RECT
>>> prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
>>> paramflags = (1, "hwnd"), (2, "lprect")
>>> GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)
>>>

Functions with output parameters will automatically return the output parametervalue if there is a single one, or a tuple containing the output parametervalues when there are more than one, so the GetWindowRect function now returns aRECT instance, when called.

Output parameters can be combined with the errcheck protocol to dofurther output processing and error checking. The win32 GetWindowRect apifunction returns a BOOL to signal success or failure, so this function coulddo the error checking, and raises an exception when the api call failed:

>>>
>>> def errcheck(result, func, args):
...     if not result:
...         raise WinError()
...     return args
...
>>> GetWindowRect.errcheck = errcheck
>>>

If the errcheck function returns the argument tuple it receivesunchanged, ctypes continues the normal processing it does on the outputparameters. If you want to return a tuple of window coordinates instead of aRECT instance, you can retrieve the fields in the function and return theminstead, the normal processing will no longer take place:

>>>
>>> def errcheck(result, func, args):
...     if not result:
...         raise WinError()
...     rc = args[1]
...     return rc.left, rc.top, rc.bottom, rc.right
...
>>> GetWindowRect.errcheck = errcheck
>>>

15.17.2.5. Utility functions

ctypes. addressof ( obj )

Returns the address of the memory buffer as integer. obj must be aninstance of a ctypes type.

ctypes. alignment ( obj_or_type )

Returns the alignment requirements of a ctypes type. obj_or_type must be actypes type or instance.

ctypes. byref ( obj [, offset ] )

Returns a light-weight pointer to obj, which must be an instance of actypes type. offset defaults to zero, and must be an integer that will beadded to the internal pointer value.

byref(obj, offset) corresponds to this C code:

(((char *)&obj) + offset)

The returned object can only be used as a foreign function callparameter. It behaves similar to pointer(obj), but theconstruction is a lot faster.

New in version 2.6: The offset optional argument was added.

ctypes. cast ( obj, type )

This function is similar to the cast operator in C. It returns a newinstance of type which points to the same memory block as obj. typemust be a pointer type, and obj must be an object that can be interpretedas a pointer.

ctypes. create_string_buffer ( init_or_size [, size ] )

This function creates a mutable character buffer. The returned object is actypes array of c_char.

init_or_size must be an integer which specifies the size of the array, or astring which will be used to initialize the array items.

If a string is specified as first argument, the buffer is made one item largerthan the length of the string so that the last element in the array is a NULtermination character. An integer can be passed as second argument which allowsto specify the size of the array if the length of the string should not be used.

If the first parameter is a unicode string, it is converted into an 8-bit stringaccording to ctypes conversion rules.

ctypes. create_unicode_buffer ( init_or_size [, size ] )

This function creates a mutable unicode character buffer. The returned object isa ctypes array of c_wchar.

init_or_size must be an integer which specifies the size of the array, or aunicode string which will be used to initialize the array items.

If a unicode string is specified as first argument, the buffer is made one itemlarger than the length of the string so that the last element in the array is aNUL termination character. An integer can be passed as second argument whichallows to specify the size of the array if the length of the string should notbe used.

If the first parameter is a 8-bit string, it is converted into an unicode stringaccording to ctypes conversion rules.

ctypes. DllCanUnloadNow ( )

Windows only: This function is a hook which allows to implement in-processCOM servers with ctypes. It is called from the DllCanUnloadNow function thatthe _ctypes extension dll exports.

ctypes. DllGetClassObject ( )

Windows only: This function is a hook which allows to implement in-processCOM servers with ctypes. It is called from the DllGetClassObject functionthat the _ctypes extension dll exports.

ctypes.util. find_library ( name )

Try to find a library and return a pathname. name is the library namewithout any prefix like lib, suffix like .so, .dylib or versionnumber (this is the form used for the posix linker option -l). Ifno library can be found, returns None.

The exact functionality is system dependent.

Changed in version 2.6: Windows only: find_library("m") or find_library("c") return theresult of a call to find_msvcrt().

ctypes.util. find_msvcrt ( )

Windows only: return the filename of the VC runtype library used by Python,and by the extension modules. If the name of the library cannot bedetermined, None is returned.

If you need to free memory, for example, allocated by an extension modulewith a call to the free(void *), it is important that you use thefunction in the same library that allocated the memory.

New in version 2.6.

ctypes. FormatError ( [ code ] )

Windows only: Returns a textual description of the error code code. If noerror code is specified, the last error code is used by calling the Windowsapi function GetLastError.

ctypes. GetLastError ( )

Windows only: Returns the last error code set by Windows in the calling thread.This function calls the Windows GetLastError() function directly,it does not return the ctypes-private copy of the error code.

ctypes. get_errno ( )

Returns the current value of the ctypes-private copy of the systemerrno variable in the calling thread.

New in version 2.6.

ctypes. get_last_error ( )

Windows only: returns the current value of the ctypes-private copy of the systemLastError variable in the calling thread.

New in version 2.6.

ctypes. memmove ( dst, src, count )

Same as the standard C memmove library function: copies count bytes fromsrc to dst. dst and src must be integers or ctypes instances that canbe converted to pointers.

ctypes. memset ( dst, c, count )

Same as the standard C memset library function: fills the memory block ataddress dst with count bytes of value c. dst must be an integerspecifying an address, or a ctypes instance.

ctypes. POINTER ( type )

This factory function creates and returns a new ctypes pointer type. Pointertypes are cached an reused internally, so calling this function repeatedly ischeap. type must be a ctypes type.

ctypes. pointer ( obj )

This function creates a new pointer instance, pointing to obj. The returnedobject is of the type POINTER(type(obj)).

Note: If you just want to pass a pointer to an object to a foreign functioncall, you should use byref(obj) which is much faster.

ctypes. resize ( obj, size )

This function resizes the internal memory buffer of obj, which must be aninstance of a ctypes type. It is not possible to make the buffer smallerthan the native size of the objects type, as given by sizeof(type(obj)),but it is possible to enlarge the buffer.

ctypes. set_conversion_mode ( encoding, errors )

This function sets the rules that ctypes objects use when converting between8-bit strings and unicode strings. encoding must be a string specifying anencoding, like 'utf-8' or 'mbcs', errors must be a stringspecifying the error handling on encoding/decoding errors. Examples ofpossible values are "strict", "replace", or "ignore".

set_conversion_mode() returns a 2-tuple containing the previousconversion rules. On windows, the initial conversion rules are ('mbcs','ignore'), on other systems ('ascii', 'strict').

ctypes. set_errno ( value )

Set the current value of the ctypes-private copy of the system errnovariable in the calling thread to value and return the previous value.

New in version 2.6.

ctypes. set_last_error ( value )

Windows only: set the current value of the ctypes-private copy of the systemLastError variable in the calling thread to value and return theprevious value.

New in version 2.6.

ctypes. sizeof ( obj_or_type )

Returns the size in bytes of a ctypes type or instance memory buffer.Does the same as the C sizeof operator.

ctypes. string_at ( address [, size ] )

This function returns the string starting at memory address address. If sizeis specified, it is used as size, otherwise the string is assumed to bezero-terminated.

ctypes. WinError ( code=None, descr=None )

Windows only: this function is probably the worst-named thing in ctypes. Itcreates an instance of WindowsError. If code is not specified,GetLastError is called to determine the error code. If descr is notspecified, FormatError() is called to get a textual description of theerror.

ctypes. wstring_at ( address [, size ] )

This function returns the wide character string starting at memory addressaddress as unicode string. If size is specified, it is used as thenumber of characters of the string, otherwise the string is assumed to bezero-terminated.

15.17.2.6. Data types

class ctypes. _CData

This non-public class is the common base class of all ctypes data types.Among other things, all ctypes type instances contain a memory block thathold C compatible data; the address of the memory block is returned by theaddressof() helper function. Another instance variable is exposed as_objects; this contains other Python objects that need to be keptalive in case the memory block contains pointers.

Common methods of ctypes data types, these are all class methods (to beexact, they are methods of the metaclass):

from_buffer ( source [, offset ] )

This method returns a ctypes instance that shares the buffer of thesource object. The source object must support the writeable bufferinterface. The optional offset parameter specifies an offset into thesource buffer in bytes; the default is zero. If the source buffer is notlarge enough a ValueError is raised.

New in version 2.6.

from_buffer_copy ( source [, offset ] )

This method creates a ctypes instance, copying the buffer from thesource object buffer which must be readable. The optional offsetparameter specifies an offset into the source buffer in bytes; the defaultis zero. If the source buffer is not large enough a ValueError israised.

New in version 2.6.

from_address ( address )

This method returns a ctypes type instance using the memory specified byaddress which must be an integer.

from_param ( obj )

This method adapts obj to a ctypes type. It is called with the actualobject used in a foreign function call when the type is present in theforeign function’s argtypes tuple; it must return an object thatcan be used as a function call parameter.

All ctypes data types have a default implementation of this classmethodthat normally returns obj if that is an instance of the type. Sometypes accept other objects as well.

in_dll ( library, name )

This method returns a ctypes type instance exported by a sharedlibrary. name is the name of the symbol that exports the data, libraryis the loaded shared library.

Common instance variables of ctypes data types:

_b_base_

Sometimes ctypes data instances do not own the memory block they contain,instead they share part of the memory block of a base object. The_b_base_ read-only member is the root ctypes object that owns thememory block.

_b_needsfree_

This read-only variable is true when the ctypes data instance hasallocated the memory block itself, false otherwise.

_objects

This member is either None or a dictionary containing Python objectsthat need to be kept alive so that the memory block contents is keptvalid. This object is only exposed for debugging; never modify thecontents of this dictionary.

15.17.2.7. Fundamental data types

class ctypes. _SimpleCData

This non-public class is the base class of all fundamental ctypes datatypes. It is mentioned here because it contains the common attributes of thefundamental ctypes data types. _SimpleCData is a subclass of_CData, so it inherits their methods and attributes.

Changed in version 2.6: ctypes data types that are not and do not contain pointers can now bepickled.

Instances have a single attribute:

value

This attribute contains the actual value of the instance. For integer andpointer types, it is an integer, for character types, it is a singlecharacter string, for character pointer types it is a Python string orunicode string.

When the value attribute is retrieved from a ctypes instance, usuallya new object is returned each time. ctypes does not implementoriginal object return, always a new object is constructed. The same istrue for all other ctypes object instances.

Fundamental data types, when returned as foreign function call results, or, forexample, by retrieving structure field members or array items, are transparentlyconverted to native Python types. In other words, if a foreign function has arestype of c_char_p, you will always receive a Python string,not a c_char_p instance.

Subclasses of fundamental data types do not inherit this behavior. So, if aforeign functions restype is a subclass of c_void_p, you willreceive an instance of this subclass from the function call. Of course, you canget the value of the pointer by accessing the value attribute.

These are the fundamental ctypes data types:

class ctypes. c_byte

Represents the C signed char datatype, and interprets the value assmall integer. The constructor accepts an optional integer initializer; nooverflow checking is done.

class ctypes. c_char

Represents the C char datatype, and interprets the value as a singlecharacter. The constructor accepts an optional string initializer, thelength of the string must be exactly one character.

class ctypes. c_char_p

Represents the C char * datatype when it points to a zero-terminatedstring. For a general character pointer that may also point to binary data,POINTER(c_char) must be used. The constructor accepts an integeraddress, or a string.

class ctypes. c_double

Represents the C double datatype. The constructor accepts anoptional float initializer.

class ctypes. c_longdouble

Represents the C long double datatype. The constructor accepts anoptional float initializer. On platforms where sizeof(long double) ==sizeof(double) it is an alias to c_double.

New in version 2.6.

class ctypes. c_float

Represents the C float datatype. The constructor accepts anoptional float initializer.

class ctypes. c_int

Represents the C signed int datatype. The constructor accepts anoptional integer initializer; no overflow checking is done. On platformswhere sizeof(int) == sizeof(long) it is an alias to c_long.

class ctypes. c_int8

Represents the C 8-bit signed int datatype. Usually an alias forc_byte.

class ctypes. c_int16

Represents the C 16-bit signed int datatype. Usually an alias forc_short.

class ctypes. c_int32

Represents the C 32-bit signed int datatype. Usually an alias forc_int.

class ctypes. c_int64

Represents the C 64-bit signed int datatype. Usually an alias forc_longlong.

class ctypes. c_long

Represents the C signed long datatype. The constructor accepts anoptional integer initializer; no overflow checking is done.

class ctypes. c_longlong

Represents the C signed long long datatype. The constructor acceptsan optional integer initializer; no overflow checking is done.

class ctypes. c_short

Represents the C signed short datatype. The constructor accepts anoptional integer initializer; no overflow checking is done.

class ctypes. c_size_t

Represents the C size_t datatype.

class ctypes. c_ssize_t

Represents the C ssize_t datatype.

New in version 2.7.

class ctypes. c_ubyte

Represents the C unsigned char datatype, it interprets the value assmall integer. The constructor accepts an optional integer initializer; nooverflow checking is done.

class ctypes. c_uint

Represents the C unsigned int datatype. The constructor accepts anoptional integer initializer; no overflow checking is done. On platformswhere sizeof(int) == sizeof(long) it is an alias for c_ulong.

class ctypes. c_uint8

Represents the C 8-bit unsigned int datatype. Usually an alias forc_ubyte.

class ctypes. c_uint16

Represents the C 16-bit unsigned int datatype. Usually an alias forc_ushort.

class ctypes. c_uint32

Represents the C 32-bit unsigned int datatype. Usually an alias forc_uint.

class ctypes. c_uint64

Represents the C 64-bit unsigned int datatype. Usually an alias forc_ulonglong.

class ctypes. c_ulong

Represents the C unsigned long datatype. The constructor accepts anoptional integer initializer; no overflow checking is done.

class ctypes. c_ulonglong

Represents the C unsigned long long datatype. The constructoraccepts an optional integer initializer; no overflow checking is done.

class ctypes. c_ushort

Represents the C unsigned short datatype. The constructor acceptsan optional integer initializer; no overflow checking is done.

class ctypes. c_void_p

Represents the C void * type. The value is represented as integer.The constructor accepts an optional integer initializer.

class ctypes. c_wchar

Represents the C wchar_t datatype, and interprets the value as asingle character unicode string. The constructor accepts an optional stringinitializer, the length of the string must be exactly one character.

class ctypes. c_wchar_p

Represents the C wchar_t * datatype, which must be a pointer to azero-terminated wide character string. The constructor accepts an integeraddress, or a string.

class ctypes. c_bool

Represent the C bool datatype (more accurately, _Bool fromC99). Its value can be True or False, and the constructor accepts any objectthat has a truth value.

New in version 2.6.

class ctypes. HRESULT

Windows only: Represents a HRESULT value, which contains success orerror information for a function or method call.

class ctypes. py_object

Represents the C PyObject * datatype. Calling this without anargument creates a NULL PyObject * pointer.

The ctypes.wintypes module provides quite some other Windows specificdata types, for example HWND, WPARAM, or DWORD. Someuseful structures like MSG or RECT are also defined.

15.17.2.8. Structured data types

class ctypes. Union ( *args, **kw )

Abstract base class for unions in native byte order.

class ctypes. BigEndianStructure ( *args, **kw )

Abstract base class for structures in big endian byte order.

class ctypes. LittleEndianStructure ( *args, **kw )

Abstract base class for structures in little endian byte order.

Structures with non-native byte order cannot contain pointer type fields, or anyother data types containing pointer type fields.

class ctypes. Structure ( *args, **kw )

Abstract base class for structures in native byte order.

Concrete structure and union types must be created by subclassing one of thesetypes, and at least define a _fields_ class variable. ctypes willcreate descriptors which allow reading and writing the fields by directattribute accesses. These are the

_fields_

A sequence defining the structure fields. The items must be 2-tuples or3-tuples. The first item is the name of the field, the second itemspecifies the type of the field; it can be any ctypes data type.

For integer type fields like c_int, a third optional item can begiven. It must be a small positive integer defining the bit width of thefield.

Field names must be unique within one structure or union. This is notchecked, only one field can be accessed when names are repeated.

It is possible to define the _fields_ class variable after theclass statement that defines the Structure subclass, this allows to createdata types that directly or indirectly reference themselves:

class List(Structure):
    pass
List._fields_ = [("pnext", POINTER(List)),
                 ...
                ]

The _fields_ class variable must, however, be defined before thetype is first used (an instance is created, sizeof() is called on it,and so on). Later assignments to the _fields_ class variable willraise an AttributeError.

Structure and union subclass constructors accept both positional and namedarguments. Positional arguments are used to initialize the fields in thesame order as they appear in the _fields_ definition, namedarguments are used to initialize the fields with the corresponding name.

It is possible to defined sub-subclasses of structure types, they inheritthe fields of the base class plus the _fields_ defined in thesub-subclass, if any.

_pack_

An optional small integer that allows to override the alignment ofstructure fields in the instance. _pack_ must already be definedwhen _fields_ is assigned, otherwise it will have no effect.

_anonymous_

An optional sequence that lists the names of unnamed (anonymous) fields._anonymous_ must be already defined when _fields_ isassigned, otherwise it will have no effect.

The fields listed in this variable must be structure or union type fields.ctypes will create descriptors in the structure type that allows toaccess the nested fields directly, without the need to create thestructure or union field.

Here is an example type (Windows):

class _U(Union):
    _fields_ = [("lptdesc", POINTER(TYPEDESC)),
                ("lpadesc", POINTER(ARRAYDESC)),
                ("hreftype", HREFTYPE)]

class TYPEDESC(Structure):
    _anonymous_ = ("u",)
    _fields_ = [("u", _U),
                ("vt", VARTYPE)]

The TYPEDESC structure describes a COM data type, the vt fieldspecifies which one of the union fields is valid. Since the u fieldis defined as anonymous field, it is now possible to access the membersdirectly off the TYPEDESC instance. td.lptdesc and td.u.lptdescare equivalent, but the former is faster since it does not need to createa temporary union instance:

td = TYPEDESC()
td.vt = VT_PTR
td.lptdesc = POINTER(some_type)
td.u.lptdesc = POINTER(some_type)

It is possible to defined sub-subclasses of structures, they inherit thefields of the base class. If the subclass definition has a separate_fields_ variable, the fields specified in this are appended to thefields of the base class.

Structure and union constructors accept both positional and keywordarguments. Positional arguments are used to initialize member fields in thesame order as they are appear in _fields_. Keyword arguments in theconstructor are interpreted as attribute assignments, so they will initialize_fields_ with the same name, or create new attributes for names notpresent in _fields_.

15.17.2.9. Arrays and pointers

Not yet written - please see the sections Pointers and sectionArrays in the tutorial.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值