[ctypes-commit] ctypes/docs updateweb.cmd,1.6,1.7 tutorial.stx,1.26,1.27 reference.stx,1.9,1.10 make
Brought to you by:
theller
Update of /cvsroot/ctypes/ctypes/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19657 Added Files: updateweb.cmd tutorial.stx reference.stx make_html.py internals.stx index.stx faq.stx default.css changes.stx .cvsignore Log Message: Moving files from branch_1_0 to HEAD. --- NEW FILE: .cvsignore --- *.html --- NEW FILE: tutorial.stx --- ctypes tutorial "overview":index.html :: tutorial :: "codegenerator":codegen.html :: "reference":reference.html :: "faq":faq.html ( Work in progress: "COM":com.html :: "COM sample":sum_sample.html ) This tutorial describes version 0.6.3 of 'ctypes'. There have been quite some changes to version 0.4.x, the most important are listed "here":changes.html. Loading dynamic link libraries 'ctypes' exports the 'cdll', and on Windows also 'windll' and 'oledll' objects to load dynamic link libraries. You load libraries by accessing them as attributes of these objects. 'cdll' loads libraries which export functions using the standard 'cdecl' calling convention, while 'windll' libraries call [...1001 lines suppressed...] Bugs, ToDo and non-implemented things Bitfields are not implemented. Enumeration types are not implemented. You can do it easily yourself, using 'c_int' as the base class. 'long double' is not implemented. <!-- no longer true: You cannot pass structures to functions as arguments, and you cannot set them as return type (only pointers). --> <!-- no longer true? Callback functions implemented in Python can *only* return integers. --> <!-- Local Variables: compile-command: "make_html" End: --> --- NEW FILE: updateweb.cmd --- REM $Id: updateweb.cmd,v 1.7 2006/03/03 20:29:52 theller Exp $ make_html -w scp ../LICENSE.txt default.css changes.html com.html faq.html index.html sum_sample.html tutorial.html reference.html th...@st...:~/public_html/ctypes/ --- NEW FILE: changes.stx --- Changes in ctypes 0.6 Version 0.6.3 A critical bug with pointer instances was fixed, this makes the 'incomplete types' sample code in the tutorial actually work. All ctypes objects are now correctly garbarge collected. This *may* lead to crashes in your program (especially with callback functions, or pointers handed out to longer running C code). You must keep a reference in Python to any object as long as it is used in foreign C code. All known bugs have been fixed. Again, a lot of changes to the COM package, but all this is still work in progress and unstable, and it has to be properly documented. Version 0.6.2 Fixed a bug which prevented callback functions to return data types other than integers. They can now also return pointers, floats, and doubles. It is now possible to pass structures and unions to function calls *by value*. Currently this works only on Windows. A lot of changes to the COM package, but all this is still work in progress and unstable, and it has to be properly documented. Version 0.6.1 'ctypes' types now have a 'in_dll(dll, symbolname)' class method. It allows to access and/or change values exported by dlls. Several bugs have been fixed. Installation 'ctypes' has been converted into a package, it is no longer a couple of modules. **This requires that you remove any previous version** of ctypes you may have installed, either (on Windows, if you have installed from the exe-file) by running the uninstaller from *Control Panel->Add/Remove Programs*, or by deleting the files 'Lib/site-packages/ctypes.py' and 'Lib/site-packages/_ctypes.pyd'. Package contents All platforms: 'ctypes' - the basic stuff mentioned in the tutorial On Windows: 'ctypes.wintypes' - defines several common windows datatypes 'ctypes.com' - the beginning of a com framework, client code as well as localserver code. This is only proof-of-concept code, the interface is *not* stable at all. 'ctypes.com.tools' - an utility 'readtlb.py' which generates Python wrapper code from type libraries. 'ctypes.com.samples' - this is not really a package, currently it contains a sample which controls Internet Explorer, and receives events. The com framework is currently undocumented, but I believe it contains quite some code which should be quite easy to read, at least for experienced com/C programmers. The basic goal of this framework is to allow easy collaboration with ATL servers and clients, it is centered around typelibraries. The source distribution contains additional code in a samples directory tree and full documentation. General It is now safe to do 'from ctypes import *', only symbols actually needed are exposed. Format characters Format characters like '"i"' or '"H"' are no longer supported anywhere. They must be replaced by the corresponding type like 'c_int' or 'c_ushort'. String formats in Structures or Unions like '"6c"' which describe an array of 6 characters must be replaced by 'c_char * 6'. Functions Again, format characters are no longer allowed as function's restype attribute. Replace them by the appropriate ctypes' type like c_char_p instead of '"s"' or '"z"' if the function returns a string pointer, for example. Callback functions The type for callback functions can no longer be defined by subclassing 'CFunction', actually this type no longer exists. The recommended way to define the type of a callback function is to call 'WINFUNCTYPE()' if you need a C-callable function pointer using the __stdcall calling convention, or 'CFUNCTYPE()' if you need a function pointer using the standard cdecl calling convention. You have to supply the result type and the expected argument types. Instances of these types are callable from C, but they are now also callable from Python directly. These types can also be used in the 'argtypes' sequence, or as the 'restype' attribute if you have a dll function expecting or returning a function pointer. Pointers Pointer *types* are created by calling 'POINTER(c_int)' for example. The 'POINTER' function maintains a cache of created types, so calling it with the same argument always returns the *same* identical type. pointer instances are usually created by 'pointer(c_int(42))' for example. 'pointer()' internally calls 'POINTER()' to get the type. c_string and c_wstring have been removed In previous versions the 'c_string' and 'c_wstring' types could be used to allocate mutable buffers and fill them from or convert them to Python strings or unicode objects. These do no longer exist. ctypes now exports a 'c_buffer()' function as a replacement. Actually 'c_buffer' returns a character array (an instance of 'c_char * size'). --- NEW FILE: faq.stx --- ctypes FAQ - frequently asked questions "overview":index.html :: "tutorial":tutorial.html :: "reference":reference.html :: faq ( Work in progress: "COM":com.html :: "COM sample":sum_sample.html ) Windows topics How do I pass a win32all 'PyHandle' to a dll function? 'win32all' functions often return a 'PyHandle' object, for example the 'CreateFile' function. 'ctypes' has it's own protocol to convert Python objects into C parameters when it calls functions loaded from a dll, so it does not know how to pass the 'PyHandle' object to the C function. 'PyHandle' objects have a '.handle' attribute which is an integer, and this can be passed to a function by 'ctypes' :: h = win32file.CreateFile(....) windll.kernel32.DeviceIoControl(h.handle, ...) Another possibility is to convert the 'PyHandle' object into an integer by writing the call in this way:: h = win32file.CreateFile(....) windll.kernel32.DeviceIoControl(int(h), ...) How can I call functions in a dll written in Delphi? Delphi uses the 'PASCAL' calling convention as default, and this expects the parameters in reverse order. Write the arguments in reverse order in the call, and it should work when using the __stdcall calling convention (load the Delphi dll with 'windll'). General topics How can I access a value (an integer, a pointer) in a shared library? **New in 0.6.1**: 'ctypes' types now have a '.in_dll' class method, which accepts a dll/shared library instance and a symbol name as parameters. See the tutorial for details. How can I load a dll named 'gpib-32.dll'? 'ctypes' loads dlls by retrieving them as attributes from 'windll' or 'cdll', like 'windll.gdi32' which loads 'gdi32.dll'. This approach cannot work when the filename contains characters not allowed in Python identifiers, or when the dll is not on the default Windows search path. In these cases you should call the 'CDLL' or 'WinDLL' classes directly with the filename:: gpib32 = CDLL("c:\\gpib\\gpib-32.dll") How can I call functions written in "C++" ? Jimmy Retzlaff explains how the C++ compiler mangles function names and how it can be avoided in this "*post*":http://sourceforge.net/mailarchive/forum.php?thread_id=1604647&forum_id=24606 to the ctypes-users mailing list. How can I help to improve this FAQ? Send new questions, better answers, or other comments to the "ctypes-users":mailto:cty...@li... mailing list. --- NEW FILE: index.stx --- The ctypes module overview :: "tutorial":tutorial.html :: "codegenerator":codegen.html :: "reference":reference.html :: "faq":faq.html ( Work in progress: "COM":com.html :: "COM sample":sum_sample.html ) Overview 'ctypes' is an advanced ffi (Foreign Function Interface) package for Python 2.3 and higher. 'ctypes' allows to call functions exposed from dlls/shared libraries and has extensive facilities to create, access and manipulate simple and complicated C data types in Python - in other words: wrap libraries in pure Python. It is even possible to implement C callback functions in pure Python. ctypes now includes a code generator toolchain which allows automatic creation of library wrappers from C header files. This feature is still experimental and beta quality. ctypes works on Windows, Mac OS X, Linux, Solaris, FreeBSD, OpenBSD. It may also run on other systems, provided that libffi supports this platform. For windows, ctypes contains a ctypes.com package which allows to call and implement custom COM interfaces. Detailed changelogs are in CVS (well, sometimes I forget to update them): "ANNOUNCE":http://cvs.sourceforge.net/viewcvs.py/ctypes/ctypes/ANNOUNCE?rev=release_0_9_6 "ChangeLog":http://cvs.sourceforge.net/viewcvs.py/ctypes/ctypes/ChangeLog?rev=HEAD "com ChangeLog":http://cvs.sourceforge.net/viewcvs.py/ctypes/ctypes/win32/com/ChangeLog?rev=HEAD News **'ctypes' version 0.9.6 has been released (Mar 18, 2005).** Thanks to all of you who reported bugs so quickly, and those who tried out the codegenerator toolchain. **The code generator is brand new and still experimental, although hopefully better than in the 0.9.5 release.** Bug fixes: - keyword arguments in Structure/Union initializers had no effect. - it was impossible to override the from_parm class method in subclasses of c_void_p, c_char_p, and c_wchar_p. - removed the __del__ method of _CDLL. It caused uncollectable garbage in Python's gc. - ctypes.com.register: enclose the Python script to run a com server in quotes, otherwise it won't run correctly when the directory name contains spaces. Enhancements: - Several changes have been made to the h2xml script from the codegenerator toolchain. See the documentation (linked below) for details. **'ctypes' version 0.9.5 has been released (Mar 11, 2005).** New package 'ctypes.wrap'. It contains decorators for easier creation of wrapper functions. This package also contains a toolchain for (semi)automatic creation of wrappers for external libraries - it can parse C header files and generate ctypes code for the declarations in them. It can even handle preprocessor definitions! For details, see "codegenerator":codegen.html On systems where sizeof(int) == sizeof(long), c_int/c_long and c_uint/c_ulong are now aliases. Similar for c_long/c_longlong and c_ulong/c_ulonglong. This prevents unneeded type errors. If an exception occurs in a callback function, a full traceback is now printed. Raising SystemExit in a callback function now correctly exists Python. HRESULT is now a proper ctype - no longer a function. This allows to use it in the argtypes sequence for function prototypes. An easier way to define structures and unions that reference themselves, or have dependencies to other data types. The _fields_ attribute can now be set *after* the Structure/Union class has been created. This makes the SetPointerType function obsolete. The semantics of the _fields_ attribute in sub-subclasses of Structure and Union has been fixed. The baseclasses _fields_ list is extended, not replaced, in subclasses. Assigning _fields_ when it is no longer possible raises an error now. Structures and unions now work as restype and in the argtypes list for functions. An important bug has been fixed with pointers. Older news 'ctypes' version 0.9.2 has been released (Oct 28, 2004): Fixed several bugs and memory leaks. 'ctypes' is now tested on Windows, Linux (x86 and x86_64), OpenBSD and Mac OS X. Implemented some helper functions: 'memmove', 'memset', 'string_at', 'wstring_at'. The former act as their C library counterpart, the latter two allow to read a zero-terminated (wide) strings at a certain address. Implemented a 'cast(cobj, ctype)' function, which creates a new object of the specified ctype from an existing object. 'ctypes' now explicitely allocates executable memory for the callbacks it creates, this makes it work correctly on platforms where executing data is normally forbidden (OpenBSD, Win XP SP2 on AMD 64). Fixed the unicode handling on non-windows platforms. Bit fields in structures and unions are now implemented. For a bit field, one would specify the width in bits as the third part in the '_fields_' list like this:: class BitFieldSample(Structure): _fields_ = [("anInt", c_int), ("aBitField", c_int, 3)] POINTER(None) now returns c_void_p. This change was made for easier code generation, and makes sense since 'None' is the ctypes way to spell 'void'. 'ctypes' 0.9.0: 'ctypes' now requires Python 2.3 or higher, Python 2.2 is no longer supported. The big change is that 'ctypes' now uses the same code base on all platforms, many, many bug should have been fixed this way on non-windows systems. There have been lots of improvements and additions both to ctypes itself, and to the ctypes.com windows framework, too many to remember now and document here. Most prominent additions to ctypes.com are: A ctypes.com.client module supporting dynamic dispatch An internet explorer toolband sample Many improvements to the stoplite sample Documentation An extensive tutorial is included in the source distribution, but also available "online":tutorial.html. You should also read the sample files in the source distribution. Downloads Recent releases can be downloaded in the "sourceforge files section":http://sourceforge.net/project/showfiles.php?group_id=71702. The source archives contain all the sources, the documentation you are reading here, and sample files in a 'samples' subdirectory. Looking at the sample files is highly recommended in addition to reading the documentation. The binary Windows distribution only everything except the documentation, the unittests, and some example scripts. These files are distributed under the "MIT license":LICENSE.txt. <!-- Local Variables: compile-command: "make_html" End: --> --- NEW FILE: make_html.py --- ############################################################################## # # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE # ############################################################################## # Hacked by Thomas Heller # # You need StructuredText from zope to build the HTML files. # Should probably switch to reST """ Document = DocumentClass.DocumentClass() HTMLNG = HTMLClass.HTMLClass() def HTML(aStructuredString, level=1, header=1): st = Basic(aStructuredString) doc = Document(st) return HTMLNG(doc,header=header,level=level) """ import os,sys from StructuredText import StructuredText import time def document(self, doc, level, output): children=doc.getChildNodes() if self.header==1: output('<html>\n') if (children and children[0].getNodeName() == 'StructuredTextSection'): output('<head>\n<title>%s</title>\n</head>\n' % children[0].getChildNodes()[0].getNodeValue()) output('<body>\n') for c in children: getattr(self, self.element_types[c.getNodeName()])(c, level, output) if self.header==1: output('</body>\n') output('</html>\n') def main(): if "-w" in sys.argv: for_web = 1 sys.argv.remove("-w") else: for_web = 0 if len(sys.argv)>1: files = sys.argv[1:] else: files = os.listdir('.') files = filter(lambda x: x.endswith('.stx'), files) for f in files: data = open(f,'r').read() st = StructuredText.Basic(data) doc = StructuredText.Document(st) html = StructuredText.HTMLNG(doc, header=0) children = doc.getChildNodes() title = children[0].getChildNodes()[0].getNodeValue() pathname = f.replace('.stx','.html') basename = os.path.splitext(pathname)[0] header = '''\ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=ISO-8859-1"> <title>%(title)s</title> <link rel="STYLESHEET" href="default.css"> </head> <body>\n''' % locals() counter = ''' <!--WEBBOT bot="HTMLMarkup" startspan ALT="Site Meter" --> <script type="text/javascript" language="JavaScript">var site="sm4sflpfw"</script> <script type="text/javascript" language="JavaScript1.2" src="http://sm4.sitemeter.com/js/counter.js?site=sm4sflpfw"> </script> <noscript> <a href="http://sm4.sitemeter.com/stats.asp?site=sm4sflpfw" target="_top"> <img src="http://sm4.sitemeter.com/meter.asp?site=sm4sflpfw" alt="Site Meter" border=0></a> </noscript> <!-- Copyright (c)2000 Site Meter --> <!--WEBBOT bot="HTMLMarkup" Endspan --> <a href="http://sourceforge.net"> <img src="http://sourceforge.net/sflogo.php?group_id=71702&type=1" width="88" height="31" border="0" alt="SourceForge.net Logo"> </a> ''' footer = ''' <hr> <!--PLACEHOLDER--> <br> <small>Page updated: %s</small> </body></html> ''' outfile = open(pathname, "w") outfile.write(header) outfile.write(html) f = footer % time.asctime() if for_web: f = f.replace("<!--PLACEHOLDER-->", counter) outfile.write(f) print pathname if __name__ == '__main__': main() --- NEW FILE: reference.stx --- ctypes reference "overview":index.html :: "tutorial":tutorial.html :: reference :: "faq":faq.html ( Work in progress: "COM":com.html :: "COM sample":sum_sample.html ) Note This reference is probably not worth it's name, so incomplete it is. Common operations on ctypes instances 'sizeof(obj) -> integer' Return an integer specifying the number of bytes in the memory block. This corresponds to the C code 'sizeof(obj)'. Does also work for types. 'byref(obj) -> cparam-object' Similar to '&obj' in C code, but only usable for passing the object as a parameter to a C function call. 'pointer(obj) -> ctypes instance' Same as '&obj' in C. Different from 'byref(obj)', this creates a new ctypes object, acting as a pointer to 'obj'. It will be an instance of a pointer class pointing to 'type(obj)' instances. The pointer class is created on the fly, if it does not yet exist. 'addressof(obj) -> integer' Same as '(int)&obj' in C. Returns the address of the internal memory buffer as an integer. Common operation on ctypes types ctypes types/classes extensively use the new Python type system, so the following may first look unusual to the Pyhon programmer. 'POINTER(ctype) -> class' Return a subclass of 'ctype'. Instances of this class are pointers to 'ctype'. The subclass will be created if it does not yet exist, otherwise it is returned from a builtin cache. 'ctype * num -> array class' Multiplying a 'ctype' class with a positive integer creates a subclass of 'Array'. Instances are arrays holding 'num' instances of 'ctype'. 'ctype.from_address(address) -> ctypes instance' Create a new instance of 'ctype' from the memory block at the integer 'address'. It must no longer be accessed if the memory block becomes invalid, the programmer must ensure this. ctypes instance methods/properties 'obj._as_parameter_ -> magic' Automatically called when a ctype object is used as a parameter in a C function call *by value*. Must *return* something that can be understood by the C function call parameter converter. Currently, it either returns an integer, a string or a unicode string. These are passed as the corresponding C data type to the function call. --- NEW FILE: internals.stx --- Purpose This file describes the implementation of the '_ctypes' module. ctypes internals 'Structure' is the most important (externally visible) part of the _ctypes module. It consists of the following building blocks: - 'StgDictObject', which is a subclass of 'PyDictObject' - 'MemoryTypeObject' metaclass, subclass of 'PyTypeObject' - 'MemoryObject', subclass of 'object' - 'CFieldObject' Among other C compatible data types implemented in the '_ctypes' module, 'Structure' instances store their attributes in a C accessible memory block. The memory block must have a certain size, combining memory blocks has certain alignment requirement, and so on. (XXX Have to explain the need for the 'length' field) StgDictObject 'StgDictObject' works around the problem that it's currently not possible to attach additional C accessible structure members to type objects. For cases where this is needed, we replace the type's 'tp_dict' member, which is normally a 'PyDictObject' instance, with a StgDictObject instance. StgInfoObject is a subclass of PyDictObject, but has additional C accessible fields:: struct { int size; int align; int length; PyObject *proto; }; These fields hold information about the memory block's requirements. MemoryTypeObject 'MemoryTypeObject' is used as the (base) metaclass for Structure and other C data types. The constructor makes sure several requirements are met (a Structure subclass must have a '_fields_' attribute, _Pointer and Array subclasses must have a '_type_' attribute, and so on). It also analyzes the memory requirements, and replaces the type's tp_dict member by a StgDictObject instance. There are C api functions to access the StgDictObject of 'type' objects:: /* * Retrieve the size, align, and length fields of the type object's * StgDictObject if it has one. Returns 0 on success. * If an error cccurrs, -1 is returned and an exception is set. */ int PyType_stginfo(PyTypeObject *self, int *psize, int *palign, int *plength); /* * Return the proto field of the type's StgDictObject, if there is one. * Returns NULL if an error occurrs, but does not set an exception. * Returns a borrowed reference. */ PyObject *PyType_spamdictproto(PyObject *self); MemoryObject This is the base class for all concrete C data types. It contains the memory block described by the type's StgDictObject. There are C api functions to access the StgDictObject of the object's type:: /* * Retrieve the size, align, and length fields of the object type's * StgDictObject if it has one. Returns 0 on success. * If an error cccurrs, -1 is returned and an exception is set. */ int PyObject_stginfo(PyObject *self, int *psize, int *palign, int *plength); /* * Return the proto field of the object type's StgDictObject, * if there is one. Returns NULL if an error occurrs, * but does not set an exception. * Returns a borrowed reference. */ PyObject *PyObject_spamdictproto(PyObject *self); CFieldObject This is a descriptor object: it knows how to convert between C and Python data types and back, and how to store and retrieve the data from the memory block. When a new subclass of Structure is created (by the metaclass), the constructor populates the new class' tp_dict with CFieldObject instances constructed from the '_fields_' attribute. --- NEW FILE: default.css --- body, th, td { font-family: verdana, Arial, sans-serif; font-size: 70%; } pre, P, DL, table { margin-left: 2em; margin-right: 2em; } H1, H2, H3, H4, H5, H6 { font-family: verdana, Arial, sans-serif; color: #000080; } H1 { /* font-size: 145%; */ font-size: 160%; } H2 { /* font-size: 130%; */ font-size: 140%; } H3 { font-size: 115%; } H4 { font-size: 100%; } table { background: #808080; } th { background: #C0C0E0; font-weight: bold; } td { background: #F0F0F0; } pre { background: #C0C0E0; font-family: Courier New, Courier, mono; font-size: 120%; padding-top: 1em; padding-bottom: 1em; } tt, code { font-family: Courier New, Courier, mono; font-size: 120%; font-weight: bold; } strong { color: #FF0000; } |