diff -r ed590800fde7 -r 75843d82f6cf Doc/library/ctypes.rst --- a/Doc/library/ctypes.rst Sun Sep 15 10:37:57 2013 +0200 +++ b/Doc/library/ctypes.rst Sun Sep 15 07:35:31 2013 -0400 @@ -20,7 +20,7 @@ they 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 :class:`c_int` type. This type is +Note: Some code samples reference the :mod:`ctypes` :class:`c_int` type. This type is an alias for the :class:`c_long` type on 32-bit systems. So, you should not be confused if :class:`c_long` is printed if you would expect :class:`c_int` --- they are actually the same type. @@ -39,7 +39,7 @@ convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and assumes the functions return a Windows :c:type:`HRESULT` error code. The error -code is used to automatically raise a :class:`OSError` exception when the +code is used to automatically raise a :exc:`OSError` exception when the function call fails. .. versionchanged:: 3.3 @@ -57,7 +57,6 @@ >>> print(cdll.msvcrt) # doctest: +WINDOWS >>> libc = cdll.msvcrt # doctest: +WINDOWS - >>> Windows appends the usual ``.dll`` file suffix automatically. @@ -71,7 +70,6 @@ >>> libc = CDLL("libc.so.6") # doctest: +LINUX >>> libc # doctest: +LINUX - >>> .. XXX Add section for Mac OS X. @@ -94,7 +92,6 @@ 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 ANSI as well as UNICODE versions of a function. The UNICODE version is exported with @@ -119,7 +116,6 @@ >>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") # doctest: +WINDOWS <_FuncPtr object at 0x...> - >>> On Windows, some dlls export functions not by name but by ordinal. These functions can be accessed by indexing the dll object with the ordinal number:: @@ -132,7 +128,6 @@ File "ctypes.py", line 310, in __getitem__ func = _StdcallFuncPtr(name, self) AttributeError: function ordinal 0 not found - >>> .. _ctypes-calling-functions: @@ -152,7 +147,6 @@ 1150640792 >>> print(hex(windll.kernel32.GetModuleHandleA(None))) # doctest: +WINDOWS 0x1d000000 - >>> :mod:`ctypes` tries to protect you from calling functions with the wrong number of arguments or the wrong calling convention. Unfortunately this only works on @@ -167,7 +161,6 @@ Traceback (most recent call last): File "", 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:: @@ -176,13 +169,11 @@ Traceback (most recent call last): File "", line 1, in ? ValueError: Procedure probably called with not enough arguments (4 bytes missing) - >>> >>> windll.msvcrt.printf(b"spam") # doctest: +WINDOWS Traceback (most recent call last): File "", 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. @@ -195,7 +186,6 @@ Traceback (most recent call last): File "", line 1, in ? OSError: exception: access violation reading 0x00000020 - >>> There are, however, enough ways to crash Python with :mod:`ctypes`, so you should be careful anyway. @@ -259,11 +249,11 @@ +----------------------+------------------------------------------+----------------------------+ | :class:`c_longdouble`| :c:type:`long double` | float | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_char_p` | :c:type:`char *` (NUL terminated) | bytes object or ``None`` | +| :class:`c_char_p` | :c:type:`char \*` (NUL terminated) | bytes object or ``None`` | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_wchar_p` | :c:type:`wchar_t *` (NUL terminated) | string or ``None`` | +| :class:`c_wchar_p` | :c:type:`wchar_t \*` (NUL terminated) | string or ``None`` | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_void_p` | :c:type:`void *` | int or ``None`` | +| :class:`c_void_p` | :c:type:`void \*` | int or ``None`` | +----------------------+------------------------------------------+----------------------------+ (1) @@ -278,7 +268,6 @@ c_wchar_p('Hello, World') >>> c_ushort(-3) c_ushort(65533) - >>> Since these types are mutable, their value can also be changed afterwards:: @@ -290,7 +279,6 @@ >>> i.value = -99 >>> print(i.value) -99 - >>> Assigning a new value to instances of the pointer types :class:`c_char_p`, :class:`c_wchar_p`, and :class:`c_void_p` changes the *memory location* they @@ -306,10 +294,9 @@ c_wchar_p('Hi, there') >>> print(s) # first object is unchanged Hello, World - >>> You should be careful, however, not to pass them to functions expecting pointers -to mutable memory. If you need mutable memory blocks, ctypes has a +to mutable memory. If you need mutable memory blocks, :mod:`ctypes` has a :func:`create_string_buffer` function which creates these in various ways. The current memory block contents can be accessed (or changed) with the ``raw`` property; if you want to access it as NUL terminated string, use the ``value`` @@ -330,11 +317,10 @@ >>> p.value = b"Hi" >>> print(sizeof(p), repr(p.raw)) 10 b'Hi\x00lo\x00\x00\x00\x00\x00' - >>> The :func:`create_string_buffer` function replaces the :func:`c_buffer` function (which is still available as an alias), as well as the :func:`c_string` function -from earlier ctypes releases. To create a mutable memory block containing +from earlier :mod:`ctypes` releases. To create a mutable memory block containing unicode characters of the C type :c:type:`wchar_t` use the :func:`create_unicode_buffer` function. @@ -362,7 +348,6 @@ Traceback (most recent call last): File "", 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, and bytes objects have to be wrapped in their corresponding :mod:`ctypes` type, so @@ -371,7 +356,6 @@ >>> printf(b"An int %d, a double %f\n", 1234, c_double(3.14)) An int 1234, a double 3.140000 31 - >>> .. _ctypes-calling-functions-with-own-custom-data-types: @@ -392,7 +376,6 @@ >>> printf(b"%d bottles of beer\n", bottles) 42 bottles of beer 19 - >>> If you don't want to store the instance's data in the :attr:`_as_parameter_` instance variable, you could define a :class:`property` which makes the @@ -416,7 +399,6 @@ >>> printf(b"String '%s', Int %d, Double %f\n", b"Hi", 10, 2.2) String 'Hi', Int 10, Double 2.200000 37 - >>> Specifying a format protects against incompatible argument types (just as a prototype for a C function), and tries to convert the arguments to valid types:: @@ -428,7 +410,6 @@ >>> printf(b"%s %d %f\n", b"X", 2, 3) X 2 3.000000 13 - >>> If you have defined your own classes which you pass to function calls, you have to implement a :meth:`from_param` class method for them to be able to use them @@ -461,7 +442,6 @@ b'def' >>> print(strchr(b"abcdef", ord("x"))) None - >>> If you want to avoid the ``ord("x")`` calls above, you can set the :attr:`argtypes` attribute, and the second argument will be converted from a @@ -479,7 +459,6 @@ None >>> strchr(b"abcdef", b"d") 'def' - >>> You can also use a callable Python object (a function or a class for example) as the :attr:`restype` attribute, if the foreign function returns an integer. The @@ -493,7 +472,6 @@ ... raise WinError() ... return value ... - >>> >>> GetModuleHandle.restype = ValidHandle # doctest: +WINDOWS >>> GetModuleHandle(None) # doctest: +WINDOWS 486539264 @@ -502,7 +480,6 @@ File "", line 1, in ? File "", line 3, in ValidHandle OSError: [Errno 126] The specified module could not be found. - >>> ``WinError`` is a function which will call Windows ``FormatMessage()`` api to get the string representation of an error code, and *returns* an exception. @@ -538,7 +515,6 @@ 3 >>> print(i.value, f.value, repr(s.value)) 1 3.1400001049 b'Hello' - >>> .. _ctypes-structures-unions: @@ -572,7 +548,6 @@ Traceback (most recent call last): File "", line 1, in ? ValueError: too many initializers - >>> You can, however, build much more complicated structures. A structure can itself contain other structures by using a structure as a field type. @@ -589,7 +564,6 @@ 0 5 >>> print(rc.lowerright.x, rc.lowerright.y) 0 0 - >>> Nested structures can also be initialized in the constructor in several ways:: @@ -603,7 +577,6 @@ >>> print(POINT.y) - >>> .. _ctypes-structureunion-alignment-byte-order: @@ -648,7 +621,6 @@ >>> print(Int.second_16) - >>> .. _ctypes-arrays: @@ -674,10 +646,8 @@ ... _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:: @@ -698,7 +668,6 @@ >>> for i in ii: print(i, end=" ") ... 1 2 3 4 5 6 7 8 9 10 - >>> .. _ctypes-pointers: @@ -712,14 +681,12 @@ >>> from ctypes import * >>> i = c_int(42) >>> pi = pointer(i) - >>> Pointer instances have a :attr:`contents` attribute which returns the object to which the pointer points, the ``i`` object above:: >>> pi.contents c_long(42) - >>> Note that :mod:`ctypes` does not have OOR (original object return), it constructs a new, equivalent object each time you retrieve an attribute:: @@ -728,7 +695,6 @@ False >>> pi.contents is pi.contents False - >>> Assigning another :class:`c_int` instance to the pointer's contents attribute would cause the pointer to point to the memory location where this is stored:: @@ -737,7 +703,6 @@ >>> pi.contents = i >>> pi.contents c_long(99) - >>> .. XXX Document dereferencing pointers, and that it is preferred over the .contents attribute. @@ -746,7 +711,6 @@ >>> pi[0] 99 - >>> Assigning to an integer index changes the pointed to value:: @@ -755,7 +719,6 @@ >>> pi[0] = 22 >>> print(i) c_long(22) - >>> It is also possible to use indexes different from 0, but you must know what you're doing, just as in C: You can access or change arbitrary memory locations. @@ -777,7 +740,6 @@ TypeError: expected c_long instead of int >>> PI(c_int(42)) - >>> Calling the pointer type without an argument creates a ``NULL`` pointer. ``NULL`` pointers have a ``False`` boolean value:: @@ -785,7 +747,6 @@ >>> null_ptr = POINTER(c_int)() >>> print(bool(null_ptr)) False - >>> :mod:`ctypes` checks for ``NULL`` when dereferencing pointers (but dereferencing invalid non-\ ``NULL`` pointers would crash Python):: @@ -794,13 +755,11 @@ Traceback (most recent call last): .... ValueError: NULL pointer access - >>> >>> null_ptr[0] = 1234 Traceback (most recent call last): .... ValueError: NULL pointer access - >>> .. _ctypes-type-conversions: @@ -808,12 +767,12 @@ Type conversions ^^^^^^^^^^^^^^^^ -Usually, ctypes does strict type checking. This means, if you have +Usually, :mod:`ctypes` does strict type checking. This means, if you have ``POINTER(c_int)`` in the :attr:`argtypes` list of a function or as the type of 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 :mod:`ctypes` accepts other objects. For example, you can pass compatible array instances instead of -pointer types. So, for ``POINTER(c_int)``, ctypes accepts an array of c_int:: +pointer types. So, for ``POINTER(c_int)``, :mod:`ctypes` accepts an array of c_int:: >>> class Bar(Structure): ... _fields_ = [("count", c_int), ("values", POINTER(c_int))] @@ -827,17 +786,15 @@ 1 2 3 - >>> In addition, if a function argument is explicitly declared to be a pointer type (such as ``POINTER(c_int)``) in :attr:`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. :mod:`ctypes` will apply the required :func:`byref` conversion in this case automatically. To set a POINTER type field to ``NULL``, you can assign ``None``:: >>> bar.values = None - >>> .. XXX list other conversions... @@ -851,20 +808,18 @@ Traceback (most recent call last): File "", line 1, in ? TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance - >>> For these cases, the :func:`cast` function is handy. -The :func:`cast` function can be used to cast a ctypes instance into a pointer -to a different ctypes data type. :func:`cast` takes two parameters, a ctypes -object that is or can be converted to a pointer of some kind, and a ctypes +The :func:`cast` function can be used to cast a :mod:`ctypes` instance into a pointer +to a different :mod:`ctypes` data type. :func:`cast` takes two parameters, a :mod:`ctypes` +object that is or can be converted to a pointer of some kind, and a :mod:`ctypes` pointer type. It returns an instance of the second argument, which references the same memory block as the first argument:: >>> a = (c_byte * 4)() >>> cast(a, POINTER(c_int)) - >>> So, :func:`cast` can be used to assign to the ``values`` field of ``Bar`` the structure:: @@ -873,7 +828,6 @@ >>> bar.values = cast((c_byte * 4)(), POINTER(c_int)) >>> print(bar.values[0]) 0 - >>> .. _ctypes-incomplete-types: @@ -892,7 +846,7 @@ struct cell *next; }; -The straightforward translation into ctypes code would be this, but it does not +The straightforward translation into :mod:`ctypes` code would be this, but it does not work:: >>> class cell(Structure): @@ -903,7 +857,6 @@ File "", line 1, in ? File "", line 2, in cell NameError: name 'cell' is not defined - >>> because the new ``class cell`` is not available in the class statement itself. In :mod:`ctypes`, we can define the ``cell`` class and set the :attr:`_fields_` @@ -915,7 +868,6 @@ ... >>> cell._fields_ = [("name", c_char_p), ... ("next", POINTER(cell))] - >>> Lets try it. We create two instances of ``cell``, and let them point to each other, and finally follow the pointer chain a few times:: @@ -932,7 +884,6 @@ ... p = p.next[0] ... foo bar foo bar foo bar foo bar - >>> .. _ctypes-callback-functions: @@ -964,7 +915,6 @@ >>> ia = IntArray5(5, 1, 7, 33, 99) >>> qsort = libc.qsort >>> qsort.restype = None - >>> :func:`qsort` must be called with a pointer to the data to sort, the number of items in the data array, the size of one item, and a pointer to the comparison @@ -976,7 +926,6 @@ integer. First we create the ``type`` for the callback function:: >>> CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int)) - >>> To get started, here is a simple callback that shows the values it gets passed:: @@ -986,7 +935,6 @@ ... return 0 ... >>> cmp_func = CMPFUNC(py_cmp_func) - >>> The result:: @@ -996,7 +944,6 @@ py_cmp_func 7 33 py_cmp_func 5 7 py_cmp_func 1 7 - >>> Now we can actually compare the two items and return a useful result:: @@ -1004,21 +951,18 @@ ... print("py_cmp_func", a[0], b[0]) ... return a[0] - b[0] ... - >>> >>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +LINUX 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 - >>> As we can easily check, our array is sorted now:: >>> for i in ia: print(i, end=" ") ... 1 5 7 33 99 - >>> **Important note for callback functions:** @@ -1044,7 +988,6 @@ >>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag") >>> print(opt_flag) c_long(0) - >>> If the interpreter would have been started with :option:`-O`, the sample would have printed ``c_long(1)``, or ``c_long(2)`` if :option:`-OO` would have been @@ -1064,20 +1007,17 @@ size, we show only how this table can be read with :mod:`ctypes`:: >>> from ctypes import * - >>> >>> class struct_frozen(Structure): ... _fields_ = [("name", c_char_p), ... ("code", POINTER(c_ubyte)), ... ("size", c_int)] ... - >>> We have defined the :c:type:`struct _frozen` data type, so we can get the pointer to the table:: >>> FrozenTable = POINTER(struct_frozen) >>> table = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules") - >>> Since ``table`` is a ``pointer`` to the array of ``struct_frozen`` records, we can iterate over it, but we just have to make sure that our loop terminates, @@ -1094,7 +1034,6 @@ __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 for @@ -1127,7 +1066,6 @@ >>> 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``. What happened? Here are the steps of the ``rc.a, rc.b = rc.b, rc.a`` line above:: @@ -1135,7 +1073,6 @@ >>> temp0, temp1 = rc.b, rc.a >>> rc.a = temp0 >>> rc.b = temp1 - >>> Note that ``temp0`` and ``temp1`` are objects still using the internal buffer of the ``rc`` object above. So executing ``rc.a = temp0`` copies the buffer @@ -1155,9 +1092,8 @@ 'abc def ghi' >>> s.value is s.value False - >>> - -Why is it printing ``False``? ctypes instances are objects containing a memory + +Why is it printing ``False``? :mod:`ctypes` instances are objects containing a memory block plus some :term:`descriptor`\s 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 again @@ -1172,7 +1108,7 @@ :mod:`ctypes` provides some support for variable-sized arrays and structures. The :func:`resize` function can be used to resize the memory buffer of an -existing ctypes object. The function takes the object as first argument, and +existing :mod:`ctypes` object. The function takes the object as first argument, and the requested size in bytes as the second argument. The memory block cannot be made smaller than the natural memory block specified by the objects type, a :exc:`ValueError` is raised if this is tried:: @@ -1189,7 +1125,6 @@ 32 >>> sizeof(type(short_array)) 8 - >>> This is nice and fine, but how would one access the additional elements contained in this array? Since the type still only knows about 4 elements, we @@ -1201,7 +1136,6 @@ Traceback (most recent call last): ... IndexError: invalid index - >>> Another way to use variable-sized data types with :mod:`ctypes` is to use the dynamic nature of Python, and (re-)define the data type after the required size @@ -1224,7 +1158,7 @@ The purpose of the :func:`find_library` function is to locate a library in a way similar to what the compiler does (on platforms with several versions of a -shared library the most recent should be loaded), while the ctypes library +shared library the most recent should be loaded), while the :mod:`ctypes` library loaders act like when a program is run, and call the runtime loader directly. The :mod:`ctypes.util` module provides a function which can help to determine @@ -1253,7 +1187,6 @@ 'libc.so.6' >>> find_library("bz2") 'libbz2.so.1.0' - >>> On OS X, :func:`find_library` tries several predefined naming schemes and paths to locate the library, and returns a full pathname if successful:: @@ -1267,7 +1200,6 @@ '/usr/lib/libbz2.dylib' >>> find_library("AGL") '/System/Library/Frameworks/AGL.framework/AGL' - >>> On Windows, :func:`find_library` searches along the system search path, and returns the full pathname, but since there is no predefined naming scheme a call @@ -1301,7 +1233,7 @@ assumed to return the windows specific :class:`HRESULT` code. :class:`HRESULT` values contain information specifying whether the function call failed or succeeded, together with additional error code. If the return value signals a - failure, an :class:`OSError` is automatically raised. + failure, an :exc:`OSError` is automatically raised. .. versionchanged:: 3.3 :exc:`WindowsError` used to be raised. @@ -1341,21 +1273,21 @@ details, consult the :manpage:`dlopen(3)` manpage, on Windows, *mode* is ignored. -The *use_errno* parameter, when set to True, enables a ctypes mechanism that +The *use_errno* parameter, when set to True, enables a :mod:`ctypes` mechanism that allows to access the system :data:`errno` error number in a safe way. :mod:`ctypes` maintains a thread-local copy of the systems :data:`errno` variable; if you call foreign functions created with ``use_errno=True`` then the -:data:`errno` value before the function call is swapped with the ctypes private +:data:`errno` value before the function call is swapped with the :mod:`ctypes` private copy, the same happens immediately after the function call. -The function :func:`ctypes.get_errno` returns the value of the ctypes private -copy, and the function :func:`ctypes.set_errno` changes the ctypes private copy +The function :func:`ctypes.get_errno` returns the value of the :mod:`ctypes` private +copy, and the function :func:`ctypes.set_errno` changes the :mod:`ctypes` private copy to a new value and returns the former value. The *use_last_error* parameter, when set to True, enables the same mechanism for the Windows error code which is managed by the :func:`GetLastError` and :func:`SetLastError` Windows API functions; :func:`ctypes.get_last_error` and -:func:`ctypes.set_last_error` are used to request and change the ctypes private +:func:`ctypes.set_last_error` are used to request and change the :mod:`ctypes` private copy of the windows error code. .. data:: RTLD_GLOBAL @@ -1463,7 +1395,7 @@ As explained in the previous section, foreign functions can be accessed as 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 :mod:`ctypes` data instances as arguments, and return the default result type specified by the library loader. They are instances of a private class: @@ -1480,19 +1412,19 @@ .. attribute:: restype - Assign a ctypes type to specify the result type of the foreign function. + Assign a :mod:`ctypes` type to specify the result type of the foreign function. Use ``None`` for :c:type:`void`, a function not returning anything. - It is possible to assign a callable Python object that is not a ctypes + It is possible to assign a callable Python object that is not a :mod:`ctypes` type, in this case the function is assumed to return a C :c:type:`int`, and the callable will be called with this integer, allowing to do further processing or error checking. Using this is deprecated, for more flexible - post processing or error checking use a ctypes data type as + post processing or error checking use a :mod:`ctypes` data type as :attr:`restype` and assign a callable to the :attr:`errcheck` attribute. .. attribute:: argtypes - Assign a tuple of ctypes types to specify the argument types that the + Assign a tuple of :mod:`ctypes` types to specify the argument types that the function accepts. Functions using the ``stdcall`` calling convention can only be called with the same number of arguments as the length of this tuple; functions using the C calling convention accept additional, @@ -1503,11 +1435,11 @@ tuple, this method allows to adapt the actual argument to an object that the foreign function accepts. For example, a :class:`c_char_p` item in the :attr:`argtypes` tuple will convert a string passed as argument into - a bytes object using ctypes conversion rules. - - New: It is now possible to put items in argtypes which are not ctypes + a bytes object using :mod:`ctypes` conversion rules. + + New: It is now possible to put items in argtypes which are not :mod:`ctypes` types, but each item must have a :meth:`from_param` method which returns a - value usable as argument (integer, string, ctypes instance). This allows + value usable as argument (integer, string, :mod:`ctypes` instance). This allows to define adapters that can adapt custom objects as function parameters. .. attribute:: errcheck @@ -1553,17 +1485,17 @@ type and the argument types of the function. -.. function:: CFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) +.. function:: CFUNCTYPE(restype, \*argtypes, use_errno=False, use_last_error=False) The returned function prototype creates functions that use the standard C calling convention. The function will release the GIL during the call. If - *use_errno* is set to True, the ctypes private copy of the system + *use_errno* is set to True, the :mod:`ctypes` private copy of the system :data:`errno` variable is exchanged with the real :data:`errno` value before and after the call; *use_last_error* does the same for the Windows error code. -.. function:: WINFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) +.. function:: WINFUNCTYPE(restype, \*argtypes, use_errno=False, use_last_error=False) Windows only: The returned function prototype creates functions that use the ``stdcall`` calling convention, except on Windows CE where @@ -1572,7 +1504,7 @@ same meaning as above. -.. function:: PYFUNCTYPE(restype, *argtypes) +.. function:: PYFUNCTYPE(restype, \*argtypes) The returned function prototype creates functions that use the Python calling convention. The function will *not* release the GIL during the call. @@ -1661,14 +1593,12 @@ >>> 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 ``GetWindowRect`` function retrieves the dimensions of a specified window by copying them into @@ -1686,13 +1616,14 @@ >>> 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 parameter 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 RECT instance, when called. +.. XXX Provide an example, and also try in/out + Output parameters can be combined with the :attr:`errcheck` protocol to do further output processing and error checking. The win32 ``GetWindowRect`` api function returns a ``BOOL`` to signal success or failure, so this function could @@ -1704,7 +1635,6 @@ ... return args ... >>> GetWindowRect.errcheck = errcheck - >>> If the :attr:`errcheck` function returns the argument tuple it receives unchanged, :mod:`ctypes` continues the normal processing it does on the output @@ -1719,7 +1649,6 @@ ... return rc.left, rc.top, rc.bottom, rc.right ... >>> GetWindowRect.errcheck = errcheck - >>> .. _ctypes-utility-functions: @@ -1730,19 +1659,19 @@ .. function:: addressof(obj) Returns the address of the memory buffer as integer. *obj* must be an - instance of a ctypes type. + instance of a :mod:`ctypes` type. .. function:: alignment(obj_or_type) - Returns the alignment requirements of a ctypes type. *obj_or_type* must be a - ctypes type or instance. + Returns the alignment requirements of a :mod:`ctypes` type. *obj_or_type* must be a + :mod:`ctypes` type or instance. .. function:: byref(obj[, offset]) Returns a light-weight pointer to *obj*, which must be an instance of a - ctypes type. *offset* defaults to zero, and must be an integer that will be + :mod:`ctypes` type. *offset* defaults to zero, and must be an integer that will be added to the internal pointer value. ``byref(obj, offset)`` corresponds to this C code:: @@ -1764,7 +1693,7 @@ .. function:: create_string_buffer(init_or_size, size=None) This function creates a mutable character buffer. The returned object is a - ctypes array of :class:`c_char`. + :mod:`ctypes` array of :class:`c_char`. *init_or_size* must be an integer which specifies the size of the array, or a bytes object which will be used to initialize the array items. @@ -1779,7 +1708,7 @@ .. function:: create_unicode_buffer(init_or_size, size=None) This function creates a mutable unicode character buffer. The returned object is - a ctypes array of :class:`c_wchar`. + a :mod:`ctypes` array of :class:`c_wchar`. *init_or_size* must be an integer which specifies the size of the array, or a string which will be used to initialize the array items. @@ -1795,14 +1724,14 @@ .. function:: DllCanUnloadNow() Windows only: This function is a hook which allows to implement in-process - COM servers with ctypes. It is called from the DllCanUnloadNow function that - the _ctypes extension dll exports. + COM servers with :mod:`ctypes`. It is called from the DllCanUnloadNow function that + the ``_ctypes`` extension dll exports. .. function:: DllGetClassObject() Windows only: This function is a hook which allows to implement in-process - COM servers with ctypes. It is called from the DllGetClassObject function + COM servers with :mod:`ctypes`. It is called from the DllGetClassObject function that the ``_ctypes`` extension dll exports. @@ -1840,22 +1769,22 @@ 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. + it does not return the :mod:`ctypes`-private copy of the error code. .. function:: get_errno() - Returns the current value of the ctypes-private copy of the system + Returns the current value of the :mod:`ctypes`-private copy of the system :data:`errno` variable in the calling thread. .. function:: get_last_error() - Windows only: returns the current value of the ctypes-private copy of the system + Windows only: returns the current value of the :mod:`ctypes`-private copy of the system :data:`LastError` variable in the calling thread. .. function:: memmove(dst, src, count) Same as the standard C memmove library function: copies *count* bytes from - *src* to *dst*. *dst* and *src* must be integers or ctypes instances that can + *src* to *dst*. *dst* and *src* must be integers or :mod:`ctypes` instances that can be converted to pointers. @@ -1863,14 +1792,14 @@ Same as the standard C memset library function: fills the memory block at address *dst* with *count* bytes of value *c*. *dst* must be an integer - specifying an address, or a ctypes instance. + specifying an address, or a :mod:`ctypes` instance. .. function:: POINTER(type) - This factory function creates and returns a new ctypes pointer type. Pointer + This factory function creates and returns a new :mod:`ctypes` pointer type. Pointer types are cached an reused internally, so calling this function repeatedly is - cheap. *type* must be a ctypes type. + cheap. *type* must be a :mod:`ctypes` type. .. function:: pointer(obj) @@ -1885,21 +1814,21 @@ .. function:: resize(obj, size) This function resizes the internal memory buffer of *obj*, which must be an - instance of a ctypes type. It is not possible to make the buffer smaller + instance of a :mod:`ctypes` type. It is not possible to make the buffer smaller than the native size of the objects type, as given by ``sizeof(type(obj))``, but it is possible to enlarge the buffer. .. function:: set_errno(value) - Set the current value of the ctypes-private copy of the system :data:`errno` + Set the current value of the :mod:`ctypes`-private copy of the system :data:`errno` variable in the calling thread to *value* and return the previous value. .. function:: set_last_error(value) - Windows only: set the current value of the ctypes-private copy of the system + Windows only: set the current value of the :mod:`ctypes`-private copy of the system :data:`LastError` variable in the calling thread to *value* and return the previous value. @@ -1907,7 +1836,7 @@ .. function:: sizeof(obj_or_type) - Returns the size in bytes of a ctypes type or instance memory buffer. Does the + Returns the size in bytes of a :mod:`ctypes` type or instance memory buffer. Does the same as the C ``sizeof()`` function. @@ -1920,8 +1849,8 @@ .. function:: WinError(code=None, descr=None) - Windows only: this function is probably the worst-named thing in ctypes. It - creates an instance of OSError. If *code* is not specified, + Windows only: this function is probably the worst-named thing in :mod:`ctypes`. It + creates an instance of :exc:`OSError`. If *code* is not specified, ``GetLastError`` is called to determine the error code. If *descr* is not specified, :func:`FormatError` is called to get a textual description of the error. @@ -1946,19 +1875,19 @@ .. class:: _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 that + This non-public class is the common base class of all :mod:`ctypes` data types. + Among other things, all :mod:`ctypes` type instances contain a memory block that hold C compatible data; the address of the memory block is returned by the :func:`addressof` helper function. Another instance variable is exposed as :attr:`_objects`; this contains other Python objects that need to be kept alive in case the memory block contains pointers. - Common methods of ctypes data types, these are all class methods (to be + Common methods of :mod:`ctypes` data types, these are all class methods (to be exact, they are methods of the :term:`metaclass`): .. method:: _CData.from_buffer(source[, offset]) - This method returns a ctypes instance that shares the buffer of the + This method returns a :mod:`ctypes` instance that shares the buffer of the *source* object. The *source* object must support the writeable buffer interface. The optional *offset* parameter specifies an offset into the source buffer in bytes; the default is zero. If the source buffer is not @@ -1967,7 +1896,7 @@ .. method:: _CData.from_buffer_copy(source[, offset]) - This method creates a ctypes instance, copying the buffer from the + This method creates a :mod:`ctypes` instance, copying the buffer from the *source* object buffer which must be readable. The optional *offset* parameter specifies an offset into the source buffer in bytes; the default is zero. If the source buffer is not large enough a :exc:`ValueError` is @@ -1975,38 +1904,38 @@ .. method:: from_address(address) - This method returns a ctypes type instance using the memory specified by + This method returns a :mod:`ctypes` type instance using the memory specified by *address* which must be an integer. .. method:: from_param(obj) - This method adapts *obj* to a ctypes type. It is called with the actual + This method adapts *obj* to a :mod:`ctypes` type. It is called with the actual object used in a foreign function call when the type is present in the foreign function's :attr:`argtypes` tuple; 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 :mod:`ctypes` data types have a default implementation of this classmethod that normally returns *obj* if that is an instance of the type. Some types accept other objects as well. .. method:: in_dll(library, name) - This method returns a ctypes type instance exported by a shared + This method returns a :mod:`ctypes` type instance exported by a shared library. *name* is the name of the symbol that exports the data, *library* is the loaded shared library. - Common instance variables of ctypes data types: + Common instance variables of :mod:`ctypes` data types: .. attribute:: _b_base_ - Sometimes ctypes data instances do not own the memory block they contain, + Sometimes :mod:`ctypes` data instances do not own the memory block they contain, instead they share part of the memory block of a base object. The - :attr:`_b_base_` read-only member is the root ctypes object that owns the + :attr:`_b_base_` read-only member is the root :mod:`ctypes` object that owns the memory block. .. attribute:: _b_needsfree_ - This read-only variable is true when the ctypes data instance has + This read-only variable is true when the :mod:`ctypes` data instance has allocated the memory block itself, false otherwise. .. attribute:: _objects @@ -2024,10 +1953,10 @@ .. class:: _SimpleCData - This non-public class is the base class of all fundamental ctypes data + This non-public class is the base class of all fundamental :mod:`ctypes` data types. It is mentioned here because it contains the common attributes of the - fundamental ctypes data types. :class:`_SimpleCData` is a subclass of - :class:`_CData`, so it inherits their methods and attributes. ctypes data + fundamental :mod:`ctypes` data types. :class:`_SimpleCData` is a subclass of + :class:`_CData`, so it inherits their methods and attributes. :mod:`ctypes` data types that are not and do not contain pointers can now be pickled. Instances have a single attribute: @@ -2039,10 +1968,10 @@ character bytes object or string, for character pointer types it is a Python bytes object or string. - When the ``value`` attribute is retrieved from a ctypes instance, usually + When the ``value`` attribute is retrieved from a :mod:`ctypes` instance, usually a new object is returned each time. :mod:`ctypes` does *not* implement original object return, always a new object is constructed. The same is - true for all other ctypes object instances. + true for all other :mod:`ctypes` object instances. Fundamental data types, when returned as foreign function call results, or, for @@ -2058,7 +1987,7 @@ receive an instance of this subclass from the function call. Of course, you can get the value of the pointer by accessing the ``value`` attribute. -These are the fundamental ctypes data types: +These are the fundamental :mod:`ctypes` data types: .. class:: c_byte @@ -2076,7 +2005,7 @@ .. class:: c_char_p - Represents the C :c:type:`char *` datatype when it points to a zero-terminated + Represents the C :c:type:`char \*` datatype when it points to a zero-terminated string. For a general character pointer that may also point to binary data, ``POINTER(c_char)`` must be used. The constructor accepts an integer address, or a bytes object. @@ -2219,7 +2148,7 @@ .. class:: c_void_p - Represents the C :c:type:`void *` type. The value is represented as integer. + Represents the C :c:type:`void \*` type. The value is represented as integer. The constructor accepts an optional integer initializer. @@ -2232,7 +2161,7 @@ .. class:: c_wchar_p - Represents the C :c:type:`wchar_t *` datatype, which must be a pointer to a + Represents the C :c:type:`wchar_t \*` datatype, which must be a pointer to a zero-terminated wide character string. The constructor accepts an integer address, or a string. @@ -2252,8 +2181,8 @@ .. class:: py_object - Represents the C :c:type:`PyObject *` datatype. Calling this without an - argument creates a ``NULL`` :c:type:`PyObject *` pointer. + Represents the C :c:type:`PyObject \*` datatype. Calling this without an + argument creates a ``NULL`` :c:type:`PyObject \*` pointer. The :mod:`ctypes.wintypes` module provides quite some other Windows specific data types, for example :c:type:`HWND`, :c:type:`WPARAM`, or :c:type:`DWORD`. Some @@ -2265,40 +2194,50 @@ Structured data types ^^^^^^^^^^^^^^^^^^^^^ - -.. class:: Union(*args, **kw) +.. class:: Union(\*args, \*\*kw) Abstract base class for unions in native byte order. -.. class:: BigEndianStructure(*args, **kw) +.. class:: BigEndianUnion(\*args, \*\*kw) + + Abstract base class for unions in *big endian* byte order. + + +.. class:: LittleEndianUnion(\*args, \*\*kw) + + Abstract base class for unions in *little endian* byte order. + + +.. class:: BigEndianStructure(\*args, \*\*kw) Abstract base class for structures in *big endian* byte order. -.. class:: LittleEndianStructure(*args, **kw) +.. class:: 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 any + +Structures and unions with non-native byte order cannot contain pointer type fields, or any other data types containing pointer type fields. -.. class:: Structure(*args, **kw) +.. class:: Structure(\*args, \*\*kw) Abstract base class for structures in *native* byte order. Concrete structure and union types must be created by subclassing one of these types, and at least define a :attr:`_fields_` class variable. :mod:`ctypes` will create :term:`descriptor`\s which allow reading and writing the fields by direct - attribute accesses. These are the + attribute accesses. .. attribute:: _fields_ A sequence defining the structure fields. The items must be 2-tuples or 3-tuples. The first item is the name of the field, the second item - specifies the type of the field; it can be any ctypes data type. + specifies the type of the field; it can be any :mod:`ctypes` data type. For integer type fields like :class:`c_int`, a third optional item can be given. It must be a small positive integer defining the bit width of the @@ -2320,16 +2259,7 @@ The :attr:`_fields_` class variable must, however, be defined before the type is first used (an instance is created, :func:`sizeof` is called on it, and so on). Later assignments to the :attr:`_fields_` class variable will - raise an AttributeError. - - Structure and union subclass constructors accept both positional and named - arguments. Positional arguments are used to initialize the fields in the - same order as they appear in the :attr:`_fields_` definition, named - arguments are used to initialize the fields with the corresponding name. - - It is possible to defined sub-subclasses of structure types, they inherit - the fields of the base class plus the :attr:`_fields_` defined in the - sub-subclass, if any. + raise an :exc:`AttributeError`. .. attribute:: _pack_ @@ -2375,8 +2305,9 @@ td.lptdesc = POINTER(some_type) td.u.lptdesc = POINTER(some_type) - It is possible to defined sub-subclasses of structures, they inherit the - fields of the base class. If the subclass definition has a separate + + It is possible to define sub-subclasses of structures, they inherit the + fields of the base class. If the sub-subclass definition has a separate :attr:`_fields_` variable, the fields specified in this are appended to the fields of the base class. @@ -2393,6 +2324,50 @@ Arrays and pointers ^^^^^^^^^^^^^^^^^^^ -Not yet written - please see the sections :ref:`ctypes-pointers` and section -:ref:`ctypes-arrays` in the tutorial. - +.. class:: Array(\*args) + + Abstract base class for arrays. + + The recommended way to create concrete array types is by multiplying any + :mod:`ctypes` data type with a positive integer. Alternatively, you can subclass + this type and define :attr:`_length_` and :attr:`_type_` class variables. + :mod:`ctypes` allows reading and writing the elements using standard + subscript and slice accesses; for slice reads, the resulting object is + *not* itself an :class:`Array`. + + + .. attribute:: _length_ + + A positive integer specifying the number of elements in the array. + Out-of-range subscripts result in an :exc:`IndexError`. Will be + returned by :func:`len`. + + + .. attribute:: _type_ + + Specifies the type of each element in the array. + + + Array subclass constructors accept positional arguments, used to + initialize the elements in order. + + +.. class:: _Pointer + + Private, abstract base class for pointers. + + Concrete pointer types are created by calling :func:`POINTER` with the + type that will be pointed to; this is done automatically by + :func:`pointer`. + + :mod:`ctypes` allows reading and writing the elements using standard + subscript and slice accesses. :class:`_Pointer` objects have no size, + so :func:`len` will raise :exc:`TypeError`, negative subscripts will + read from the memory *before* the pointer (as in C), and out-of-range + subscripts will probably crash with an access violation (if you're lucky). + + + .. attribute:: _type_ + + Specifies the type pointed to. + diff -r ed590800fde7 -r 75843d82f6cf Lib/ctypes/__init__.py --- a/Lib/ctypes/__init__.py Sun Sep 15 10:37:57 2013 +0200 +++ b/Lib/ctypes/__init__.py Sun Sep 15 07:35:31 2013 -0400 @@ -524,6 +524,7 @@ return ccom.DllCanUnloadNow() from ctypes._endian import BigEndianStructure, LittleEndianStructure +from ctypes._endian import BigEndianUnion, LittleEndianUnion # Fill in specifically-sized types c_int8 = c_byte diff -r ed590800fde7 -r 75843d82f6cf Lib/ctypes/_endian.py --- a/Lib/ctypes/_endian.py Sun Sep 15 10:37:57 2013 +0200 +++ b/Lib/ctypes/_endian.py Sun Sep 15 07:35:31 2013 -0400 @@ -20,7 +20,7 @@ return typ raise TypeError("This type does not support other endian: %s" % typ) -class _swapped_meta(type(Structure)): +class _swapped_meta: def __setattr__(self, attrname, value): if attrname == "_fields_": fields = [] @@ -31,6 +31,8 @@ fields.append((name, _other_endian(typ)) + rest) value = fields super().__setattr__(attrname, value) +class _swapped_struct_meta(_swapped_meta, type(Structure)): pass +class _swapped_union_meta(_swapped_meta, type(Union)): pass ################################################################ @@ -42,18 +44,27 @@ _OTHER_ENDIAN = "__ctype_be__" LittleEndianStructure = Structure + class BigEndianStructure(Structure, metaclass=_swapped_struct_meta): + """Structure with big endian byte order""" + _swappedbytes_ = None - class BigEndianStructure(Structure, metaclass=_swapped_meta): - """Structure with big endian byte order""" + LittleEndianUnion = Union + class BigEndianUnion(Union, metaclass=_swapped_union_meta): + """Union with big endian byte order""" _swappedbytes_ = None elif sys.byteorder == "big": _OTHER_ENDIAN = "__ctype_le__" BigEndianStructure = Structure - class LittleEndianStructure(Structure, metaclass=_swapped_meta): + class LittleEndianStructure(Structure, metaclass=_swapped_struct_meta): """Structure with little endian byte order""" _swappedbytes_ = None + BigEndianUnion = Union + class LittleEndianUnion(Union, metaclass=_swapped_union_meta): + """Union with little endian byte order""" + _swappedbytes_ = None + else: raise RuntimeError("Invalid byteorder") diff -r ed590800fde7 -r 75843d82f6cf Lib/ctypes/test/test_arrays.py --- a/Lib/ctypes/test/test_arrays.py Sun Sep 15 10:37:57 2013 +0200 +++ b/Lib/ctypes/test/test_arrays.py Sun Sep 15 07:35:31 2013 -0400 @@ -22,20 +22,24 @@ self.assertEqual(len(ia), alen) # slot values ok? - values = [ia[i] for i in range(len(init))] + values = [ia[i] for i in range(alen)] self.assertEqual(values, init) + # out-of-bounds accesses should be caught + with self.assertRaises(IndexError): ia[alen] + with self.assertRaises(IndexError): ia[-alen-1] + # change the items from operator import setitem new_values = list(range(42, 42+alen)) [setitem(ia, n, new_values[n]) for n in range(alen)] - values = [ia[i] for i in range(len(init))] + values = [ia[i] for i in range(alen)] self.assertEqual(values, new_values) # are the items initialized to 0? ia = int_array() - values = [ia[i] for i in range(len(init))] - self.assertEqual(values, [0] * len(init)) + values = [ia[i] for i in range(alen)] + self.assertEqual(values, [0] * alen) # Too many initializers should be caught self.assertRaises(IndexError, int_array, *range(alen*2)) diff -r ed590800fde7 -r 75843d82f6cf Lib/ctypes/test/test_byteswap.py --- a/Lib/ctypes/test/test_byteswap.py Sun Sep 15 10:37:57 2013 +0200 +++ b/Lib/ctypes/test/test_byteswap.py Sun Sep 15 07:35:31 2013 -0400 @@ -290,5 +290,68 @@ s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14) self.assertEqual(bin(s1), bin(s2)) + def test_union_fields(self): + if sys.byteorder == "little": + base = BigEndianUnion + else: + base = LittleEndianUnion + + class T(base): + pass + _fields_ = [("a", c_ubyte), + ("b", c_byte), + ("c", c_short), + ("d", c_ushort), + ("e", c_int), + ("f", c_uint), + ("g", c_long), + ("h", c_ulong), + ("i", c_longlong), + ("k", c_ulonglong), + ("l", c_float), + ("m", c_double), + ("n", c_char), + + ("b1", c_byte, 3), + ("b2", c_byte, 3), + ("b3", c_byte, 2), + ("a", c_int * 3 * 3 * 3)] + T._fields_ = _fields_ + + # these fields do not support different byte order: + for typ in c_wchar, c_void_p, POINTER(c_int): + _fields_.append(("x", typ)) + class T(base): + pass + self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + + def test_union_struct(self): + # nested structures in unions with different byteorders + + # create nested structures in unions with given byteorders and set memory to data + + for nested, data in ( + (BigEndianStructure, b'\0\0\0\1\0\0\0\2'), + (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'), + ): + for parent in ( + BigEndianUnion, + LittleEndianUnion, + Union, + ): + class NestedStructure(nested): + _fields_ = [("x", c_uint32), + ("y", c_uint32)] + + class TestUnion(parent): + _fields_ = [("point", NestedStructure)] + + self.assertEqual(len(data), sizeof(TestUnion)) + ptr = POINTER(TestUnion) + s = cast(data, ptr)[0] + del ctypes._pointer_type_cache[TestUnion] + self.assertEqual(s.point.x, 1) + self.assertEqual(s.point.y, 2) + if __name__ == "__main__": unittest.main() diff -r ed590800fde7 -r 75843d82f6cf Lib/ctypes/test/test_pointers.py --- a/Lib/ctypes/test/test_pointers.py Sun Sep 15 10:37:57 2013 +0200 +++ b/Lib/ctypes/test/test_pointers.py Sun Sep 15 07:35:31 2013 -0400 @@ -128,9 +128,10 @@ def test_basic(self): p = pointer(c_int(42)) - # Although a pointer can be indexed, it ha no length + # Although a pointer can be indexed, it has no length self.assertRaises(TypeError, len, p) self.assertEqual(p[0], 42) + self.assertEqual(p[0:1], [42]) self.assertEqual(p.contents.value, 42) def test_charpp(self):