[ctypes-commit] ctypes/docs/manual tutorial.txt,1.22,1.23
Brought to you by:
theller
From: Thomas H. <th...@us...> - 2006-04-19 19:23:09
|
Update of /cvsroot/ctypes/ctypes/docs/manual In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7392 Modified Files: tutorial.txt Log Message: *** empty log message *** Index: tutorial.txt =================================================================== RCS file: /cvsroot/ctypes/ctypes/docs/manual/tutorial.txt,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** tutorial.txt 19 Apr 2006 18:48:58 -0000 1.22 --- tutorial.txt 19 Apr 2006 19:23:06 -0000 1.23 *************** *** 704,721 **** ---------------- - **Note:** This code seems to work in older versions, but the past - convention was to use the now deprecated ``SetPointerType`` function. - If you have an older version and the following example does not work - for you, try looking up that function. - *Incomplete Types* are structures, unions or arrays whose members are ! not yet specified. In the ``ctypes`` context, you can create types ! representing pointers to these incomplete types by passing their name ! (as a string) to the POINTER function, and complete the result ! subclass later. ! ! Consider this example (C-code):: ! struct cell; struct { --- 704,712 ---- ---------------- *Incomplete Types* are structures, unions or arrays whose members are ! not yet specified. In C, they are specified by forward declarations, which ! are defined later:: ! struct cell; /* forward declaration */ struct { *************** *** 738,745 **** because the new ``class cell`` is not available in the class statement ! itself. ! ! We can do it by creating an *incomplete type*. Just leave out the ! ``_fields_`` declaration and fill it up later:: >>> from ctypes import * --- 729,734 ---- 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 * *************** *** 776,787 **** First, you must create a class for the callback function, the class ! knows the calling convention, the result type the function has to ! return, and the number and types of the arguments this function will ! receive. ! ``ctypes`` provides the CFUNCTYPE factory function to create types for ! callback functions using the normal cdecl calling convention, and, on ! Windows, the WINFUNCTYPE factory function to create types for callback ! functions using the stdcall calling convention. Both of these factory functions are called with the result type as --- 765,775 ---- First, you must create a class for the callback function, the class ! knows the calling convention, the return type, and the number and ! types of arguments this function will receive. ! The CFUNCTYPE factory function creates types for callback functions ! using the normal cdecl calling convention, and, on Windows, the ! WINFUNCTYPE factory function creates types for callback functions ! using the stdcall calling convention. Both of these factory functions are called with the result type as *************** *** 801,809 **** ``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 the sort ! function, which is the callback. The callback function will then be called with two pointers to items, and it must return a negative ! integer if the first item is smaller than the second, a 0 if they are ! equal, and a positive integer else. So our callback function receives pointers to integers, and must --- 789,797 ---- ``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 function, the callback. The callback will then be called with two pointers to items, and it must return a negative ! integer if the first item is smaller than the second, a zero if they ! are equal, and a positive integer else. So our callback function receives pointers to integers, and must *************** *** 815,819 **** For the first implementation of the callback function, we simply print ! the arguments we get, and return 0 (incremental development):: >>> def py_cmp_func(a, b): --- 803,807 ---- For the first implementation of the callback function, we simply print ! the arguments we get, and return 0 (incremental development ;-):: >>> def py_cmp_func(a, b): *************** *** 823,827 **** >>> ! Create the C callable function:: >>> cmp_func = CMPFUNC(py_cmp_func) --- 811,815 ---- >>> ! Create the C callable callback:: >>> cmp_func = CMPFUNC(py_cmp_func) *************** *** 878,882 **** >>> ! Ah, we're nearly done! Last refinements:: >>> def py_cmp_func(a, b): --- 866,871 ---- >>> ! Ah, we're nearly done! The last step is to actually compare the two ! items and return a useful result:: >>> def py_cmp_func(a, b): *************** *** 886,890 **** >>> ! Windows:: >>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +WINDOWS --- 875,879 ---- >>> ! Final run on Windows:: >>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +WINDOWS *************** *** 901,905 **** >>> ! Linux:: >>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +LINUX --- 890,894 ---- >>> ! and on Linux:: >>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +LINUX *************** *** 928,940 **** Sometimes, a dll not only exports functions, it also exports ! values. Examples in the Python dll itself are the ``Py_OptimizeFlag``, ! an integer set to 0, 1, or 2, depending on the ``-O`` or ``-OO`` flag ! given on startup. ! Starting with version 0.6.1, ``ctypes`` can access values like this ! with the ``in_dll`` class methods of the types. The following examples ! only work on Windows:: - >>> from ctypes import * >>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag") >>> print opt_flag --- 917,928 ---- Sometimes, a dll not only exports functions, it also exports ! values. An example in the Python library itself is the ! ``Py_OptimizeFlag``, an integer set to 0, 1, or 2, depending on the ! ``-O`` or ``-OO`` flag given on startup. ! ``ctypes`` can access values like this with the ``in_dll`` class ! methods of the type. ``pythonapi`` ìs a predefined symbol giving ! access to the Python C api:: >>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag") >>> print opt_flag *************** *** 946,950 **** been specified. ! A somewhat extended example which also demontrates the use of pointers accesses the ``PyImport_FrozenModules`` pointer exported by Python. --- 934,938 ---- been specified. ! An extended example which also demonstrates the use of pointers accesses the ``PyImport_FrozenModules`` pointer exported by Python. *************** *** 968,974 **** >>> ! XXX Should use pythonapi instead!!! ! We have ``loaded`` the Python dll and defined the ``struct _frozen`` ! data type, so we can get the pointer to the table:: >>> FrozenTable = POINTER(struct_frozen) --- 956,961 ---- >>> ! We have defined the ``struct _frozen`` data type, so we can get the ! pointer to the table:: >>> FrozenTable = POINTER(struct_frozen) *************** *** 976,984 **** >>> ! Since ``table`` is a ``pointer`` to the ``struct_frozen`` records, we ! can iterate over it, we just have to make sure that our loop ! terminates, because pointers have no size. Sooner or later it would ! probably crash with an access violation or whatever, so it's better to ! break out of the loop when we hit the NULL entry:: >>> for item in table: --- 963,971 ---- >>> ! 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, because pointers have no size. Sooner or later it ! would probably crash with an access violation or whatever, so it's ! better to break out of the loop when we hit the NULL entry:: >>> for item in table: *************** *** 994,998 **** The fact that standard Python has a frozen module and a frozen package ! (indicated by the negative size member) is not wellknown, AFAIK it is used for testing. Try it out with ``import __hello__`` for example. --- 981,985 ---- The fact that standard Python has a frozen module and a frozen package ! (indicated by the negative size member) is not wellknown, it is only used for testing. Try it out with ``import __hello__`` for example. *************** *** 1003,1007 **** --------- ! There are some corners in ``ctypes`` where you may be expect something else than what actually happens. --- 990,994 ---- --------- ! There are some edges in ``ctypes`` where you may be expect something else than what actually happens. *************** *** 1040,1052 **** Keep in mind that retrieving subobjects from Structure, Unions, and ! Arrays doesn't *copy* the subobject, it does more retrieve a wrapper object accessing the root-object's underlying buffer. Bugs, ToDo and non-implemented things ------------------------------------- - XXX Wrong - Enumeration types are not implemented. You can do it easily yourself, using ``c_int`` as the base class. --- 1027,1054 ---- Keep in mind that retrieving subobjects from Structure, Unions, and ! Arrays doesn't *copy* the subobject, instead it retrieves a wrapper object accessing the 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 memory block 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 again constructs a new Python each time! + + Bugs, ToDo and non-implemented things ------------------------------------- Enumeration types are not implemented. You can do it easily yourself, using ``c_int`` as the base class. |