Tweak the comments and formatting.
[python.git] / Lib / ctypes / __init__.py
blob41d39dc93f12ef0c51bdd13c866250856078b880
1 ######################################################################
2 # This file should be kept compatible with Python 2.3, see PEP 291. #
3 ######################################################################
4 """create and manipulate C data types in Python"""
6 import os as _os, sys as _sys
8 __version__ = "1.1.0"
10 from _ctypes import Union, Structure, Array
11 from _ctypes import _Pointer
12 from _ctypes import CFuncPtr as _CFuncPtr
13 from _ctypes import __version__ as _ctypes_version
14 from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
15 from _ctypes import ArgumentError
17 from struct import calcsize as _calcsize
19 if __version__ != _ctypes_version:
20 raise Exception("Version number mismatch", __version__, _ctypes_version)
22 if _os.name in ("nt", "ce"):
23 from _ctypes import FormatError
25 DEFAULT_MODE = RTLD_LOCAL
26 if _os.name == "posix" and _sys.platform == "darwin":
27 # On OS X 10.3, we use RTLD_GLOBAL as default mode
28 # because RTLD_LOCAL does not work at least on some
29 # libraries. OS X 10.3 is Darwin 7, so we check for
30 # that.
32 if int(_os.uname()[2].split('.')[0]) < 8:
33 DEFAULT_MODE = RTLD_GLOBAL
35 from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
36 FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI
38 """
39 WINOLEAPI -> HRESULT
40 WINOLEAPI_(type)
42 STDMETHODCALLTYPE
44 STDMETHOD(name)
45 STDMETHOD_(type, name)
47 STDAPICALLTYPE
48 """
50 def create_string_buffer(init, size=None):
51 """create_string_buffer(aString) -> character array
52 create_string_buffer(anInteger) -> character array
53 create_string_buffer(aString, anInteger) -> character array
54 """
55 if isinstance(init, (str, unicode)):
56 if size is None:
57 size = len(init)+1
58 buftype = c_char * size
59 buf = buftype()
60 buf.value = init
61 return buf
62 elif isinstance(init, (int, long)):
63 buftype = c_char * init
64 buf = buftype()
65 return buf
66 raise TypeError(init)
68 def c_buffer(init, size=None):
69 ## "deprecated, use create_string_buffer instead"
70 ## import warnings
71 ## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
72 ## DeprecationWarning, stacklevel=2)
73 return create_string_buffer(init, size)
75 _c_functype_cache = {}
76 def CFUNCTYPE(restype, *argtypes):
77 """CFUNCTYPE(restype, *argtypes) -> function prototype.
79 restype: the result type
80 argtypes: a sequence specifying the argument types
82 The function prototype can be called in different ways to create a
83 callable object:
85 prototype(integer address) -> foreign function
86 prototype(callable) -> create and return a C callable function from callable
87 prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
88 prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
89 prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
90 """
91 try:
92 return _c_functype_cache[(restype, argtypes)]
93 except KeyError:
94 class CFunctionType(_CFuncPtr):
95 _argtypes_ = argtypes
96 _restype_ = restype
97 _flags_ = _FUNCFLAG_CDECL
98 _c_functype_cache[(restype, argtypes)] = CFunctionType
99 return CFunctionType
101 if _os.name in ("nt", "ce"):
102 from _ctypes import LoadLibrary as _dlopen
103 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
104 if _os.name == "ce":
105 # 'ce' doesn't have the stdcall calling convention
106 _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
108 _win_functype_cache = {}
109 def WINFUNCTYPE(restype, *argtypes):
110 # docstring set later (very similar to CFUNCTYPE.__doc__)
111 try:
112 return _win_functype_cache[(restype, argtypes)]
113 except KeyError:
114 class WinFunctionType(_CFuncPtr):
115 _argtypes_ = argtypes
116 _restype_ = restype
117 _flags_ = _FUNCFLAG_STDCALL
118 _win_functype_cache[(restype, argtypes)] = WinFunctionType
119 return WinFunctionType
120 if WINFUNCTYPE.__doc__:
121 WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
123 elif _os.name == "posix":
124 from _ctypes import dlopen as _dlopen
126 from _ctypes import sizeof, byref, addressof, alignment, resize
127 from _ctypes import _SimpleCData
129 def _check_size(typ, typecode=None):
130 # Check if sizeof(ctypes_type) against struct.calcsize. This
131 # should protect somewhat against a misconfigured libffi.
132 from struct import calcsize
133 if typecode is None:
134 # Most _type_ codes are the same as used in struct
135 typecode = typ._type_
136 actual, required = sizeof(typ), calcsize(typecode)
137 if actual != required:
138 raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
139 (typ, actual, required))
141 class py_object(_SimpleCData):
142 _type_ = "O"
143 def __repr__(self):
144 try:
145 return super(py_object, self).__repr__()
146 except ValueError:
147 return "%s(<NULL>)" % type(self).__name__
148 _check_size(py_object, "P")
150 class c_short(_SimpleCData):
151 _type_ = "h"
152 _check_size(c_short)
154 class c_ushort(_SimpleCData):
155 _type_ = "H"
156 _check_size(c_ushort)
158 class c_long(_SimpleCData):
159 _type_ = "l"
160 _check_size(c_long)
162 class c_ulong(_SimpleCData):
163 _type_ = "L"
164 _check_size(c_ulong)
166 if _calcsize("i") == _calcsize("l"):
167 # if int and long have the same size, make c_int an alias for c_long
168 c_int = c_long
169 c_uint = c_ulong
170 else:
171 class c_int(_SimpleCData):
172 _type_ = "i"
173 _check_size(c_int)
175 class c_uint(_SimpleCData):
176 _type_ = "I"
177 _check_size(c_uint)
179 class c_float(_SimpleCData):
180 _type_ = "f"
181 _check_size(c_float)
183 class c_double(_SimpleCData):
184 _type_ = "d"
185 _check_size(c_double)
187 class c_longdouble(_SimpleCData):
188 _type_ = "g"
189 if sizeof(c_longdouble) == sizeof(c_double):
190 c_longdouble = c_double
192 if _calcsize("l") == _calcsize("q"):
193 # if long and long long have the same size, make c_longlong an alias for c_long
194 c_longlong = c_long
195 c_ulonglong = c_ulong
196 else:
197 class c_longlong(_SimpleCData):
198 _type_ = "q"
199 _check_size(c_longlong)
201 class c_ulonglong(_SimpleCData):
202 _type_ = "Q"
203 ## def from_param(cls, val):
204 ## return ('d', float(val), val)
205 ## from_param = classmethod(from_param)
206 _check_size(c_ulonglong)
208 class c_ubyte(_SimpleCData):
209 _type_ = "B"
210 c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
211 # backward compatibility:
212 ##c_uchar = c_ubyte
213 _check_size(c_ubyte)
215 class c_byte(_SimpleCData):
216 _type_ = "b"
217 c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
218 _check_size(c_byte)
220 class c_char(_SimpleCData):
221 _type_ = "c"
222 c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
223 _check_size(c_char)
225 class c_char_p(_SimpleCData):
226 _type_ = "z"
227 if _os.name == "nt":
228 def __repr__(self):
229 if not windll.kernel32.IsBadStringPtrA(self, -1):
230 return "%s(%r)" % (self.__class__.__name__, self.value)
231 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
232 else:
233 def __repr__(self):
234 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
235 _check_size(c_char_p, "P")
237 class c_void_p(_SimpleCData):
238 _type_ = "P"
239 c_voidp = c_void_p # backwards compatibility (to a bug)
240 _check_size(c_void_p)
242 class c_bool(_SimpleCData):
243 _type_ = "?"
245 from _ctypes import POINTER, pointer, _pointer_type_cache
247 try:
248 from _ctypes import set_conversion_mode
249 except ImportError:
250 pass
251 else:
252 if _os.name in ("nt", "ce"):
253 set_conversion_mode("mbcs", "ignore")
254 else:
255 set_conversion_mode("ascii", "strict")
257 class c_wchar_p(_SimpleCData):
258 _type_ = "Z"
260 class c_wchar(_SimpleCData):
261 _type_ = "u"
263 POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param
265 def create_unicode_buffer(init, size=None):
266 """create_unicode_buffer(aString) -> character array
267 create_unicode_buffer(anInteger) -> character array
268 create_unicode_buffer(aString, anInteger) -> character array
270 if isinstance(init, (str, unicode)):
271 if size is None:
272 size = len(init)+1
273 buftype = c_wchar * size
274 buf = buftype()
275 buf.value = init
276 return buf
277 elif isinstance(init, (int, long)):
278 buftype = c_wchar * init
279 buf = buftype()
280 return buf
281 raise TypeError(init)
283 POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param
285 # XXX Deprecated
286 def SetPointerType(pointer, cls):
287 if _pointer_type_cache.get(cls, None) is not None:
288 raise RuntimeError("This type already exists in the cache")
289 if id(pointer) not in _pointer_type_cache:
290 raise RuntimeError("What's this???")
291 pointer.set_type(cls)
292 _pointer_type_cache[cls] = pointer
293 del _pointer_type_cache[id(pointer)]
295 # XXX Deprecated
296 def ARRAY(typ, len):
297 return typ * len
299 ################################################################
302 class CDLL(object):
303 """An instance of this class represents a loaded dll/shared
304 library, exporting functions using the standard C calling
305 convention (named 'cdecl' on Windows).
307 The exported functions can be accessed as attributes, or by
308 indexing with the function name. Examples:
310 <obj>.qsort -> callable object
311 <obj>['qsort'] -> callable object
313 Calling the functions releases the Python GIL during the call and
314 reacquires it afterwards.
316 class _FuncPtr(_CFuncPtr):
317 _flags_ = _FUNCFLAG_CDECL
318 _restype_ = c_int # default, can be overridden in instances
320 def __init__(self, name, mode=DEFAULT_MODE, handle=None):
321 self._name = name
322 if handle is None:
323 self._handle = _dlopen(self._name, mode)
324 else:
325 self._handle = handle
327 def __repr__(self):
328 return "<%s '%s', handle %x at %x>" % \
329 (self.__class__.__name__, self._name,
330 (self._handle & (_sys.maxint*2 + 1)),
331 id(self) & (_sys.maxint*2 + 1))
333 def __getattr__(self, name):
334 if name.startswith('__') and name.endswith('__'):
335 raise AttributeError(name)
336 func = self.__getitem__(name)
337 setattr(self, name, func)
338 return func
340 def __getitem__(self, name_or_ordinal):
341 func = self._FuncPtr((name_or_ordinal, self))
342 if not isinstance(name_or_ordinal, (int, long)):
343 func.__name__ = name_or_ordinal
344 return func
346 class PyDLL(CDLL):
347 """This class represents the Python library itself. It allows to
348 access Python API functions. The GIL is not released, and
349 Python exceptions are handled correctly.
351 class _FuncPtr(_CFuncPtr):
352 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
353 _restype_ = c_int # default, can be overridden in instances
355 if _os.name in ("nt", "ce"):
357 class WinDLL(CDLL):
358 """This class represents a dll exporting functions using the
359 Windows stdcall calling convention.
361 class _FuncPtr(_CFuncPtr):
362 _flags_ = _FUNCFLAG_STDCALL
363 _restype_ = c_int # default, can be overridden in instances
365 # XXX Hm, what about HRESULT as normal parameter?
366 # Mustn't it derive from c_long then?
367 from _ctypes import _check_HRESULT, _SimpleCData
368 class HRESULT(_SimpleCData):
369 _type_ = "l"
370 # _check_retval_ is called with the function's result when it
371 # is used as restype. It checks for the FAILED bit, and
372 # raises a WindowsError if it is set.
374 # The _check_retval_ method is implemented in C, so that the
375 # method definition itself is not included in the traceback
376 # when it raises an error - that is what we want (and Python
377 # doesn't have a way to raise an exception in the caller's
378 # frame).
379 _check_retval_ = _check_HRESULT
381 class OleDLL(CDLL):
382 """This class represents a dll exporting functions using the
383 Windows stdcall calling convention, and returning HRESULT.
384 HRESULT error values are automatically raised as WindowsError
385 exceptions.
387 class _FuncPtr(_CFuncPtr):
388 _flags_ = _FUNCFLAG_STDCALL
389 _restype_ = HRESULT
391 class LibraryLoader(object):
392 def __init__(self, dlltype):
393 self._dlltype = dlltype
395 def __getattr__(self, name):
396 if name[0] == '_':
397 raise AttributeError(name)
398 dll = self._dlltype(name)
399 setattr(self, name, dll)
400 return dll
402 def __getitem__(self, name):
403 return getattr(self, name)
405 def LoadLibrary(self, name):
406 return self._dlltype(name)
408 cdll = LibraryLoader(CDLL)
409 pydll = LibraryLoader(PyDLL)
411 if _os.name in ("nt", "ce"):
412 pythonapi = PyDLL("python dll", None, _sys.dllhandle)
413 elif _sys.platform == "cygwin":
414 pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
415 else:
416 pythonapi = PyDLL(None)
419 if _os.name in ("nt", "ce"):
420 windll = LibraryLoader(WinDLL)
421 oledll = LibraryLoader(OleDLL)
423 if _os.name == "nt":
424 GetLastError = windll.kernel32.GetLastError
425 else:
426 GetLastError = windll.coredll.GetLastError
428 def WinError(code=None, descr=None):
429 if code is None:
430 code = GetLastError()
431 if descr is None:
432 descr = FormatError(code).strip()
433 return WindowsError(code, descr)
435 _pointer_type_cache[None] = c_void_p
437 if sizeof(c_uint) == sizeof(c_void_p):
438 c_size_t = c_uint
439 elif sizeof(c_ulong) == sizeof(c_void_p):
440 c_size_t = c_ulong
441 elif sizeof(c_ulonglong) == sizeof(c_void_p):
442 c_size_t = c_ulonglong
444 # functions
446 from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
448 ## void *memmove(void *, const void *, size_t);
449 memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
451 ## void *memset(void *, int, size_t)
452 memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
454 def PYFUNCTYPE(restype, *argtypes):
455 class CFunctionType(_CFuncPtr):
456 _argtypes_ = argtypes
457 _restype_ = restype
458 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
459 return CFunctionType
461 _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
462 def cast(obj, typ):
463 return _cast(obj, obj, typ)
465 _string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
466 def string_at(ptr, size=-1):
467 """string_at(addr[, size]) -> string
469 Return the string at addr."""
470 return _string_at(ptr, size)
472 try:
473 from _ctypes import _wstring_at_addr
474 except ImportError:
475 pass
476 else:
477 _wstring_at = CFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
478 def wstring_at(ptr, size=-1):
479 """wstring_at(addr[, size]) -> string
481 Return the string at addr."""
482 return _wstring_at(ptr, size)
485 if _os.name in ("nt", "ce"): # COM stuff
486 def DllGetClassObject(rclsid, riid, ppv):
487 try:
488 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
489 except ImportError:
490 return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
491 else:
492 return ccom.DllGetClassObject(rclsid, riid, ppv)
494 def DllCanUnloadNow():
495 try:
496 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
497 except ImportError:
498 return 0 # S_OK
499 return ccom.DllCanUnloadNow()
501 from ctypes._endian import BigEndianStructure, LittleEndianStructure
503 # Fill in specifically-sized types
504 c_int8 = c_byte
505 c_uint8 = c_ubyte
506 for kind in [c_short, c_int, c_long, c_longlong]:
507 if sizeof(kind) == 2: c_int16 = kind
508 elif sizeof(kind) == 4: c_int32 = kind
509 elif sizeof(kind) == 8: c_int64 = kind
510 for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
511 if sizeof(kind) == 2: c_uint16 = kind
512 elif sizeof(kind) == 4: c_uint32 = kind
513 elif sizeof(kind) == 8: c_uint64 = kind
514 del(kind)
516 # XXX for whatever reasons, creating the first instance of a callback
517 # function is needed for the unittests on Win64 to succeed. This MAY
518 # be a compiler bug, since the problem occurs only when _ctypes is
519 # compiled with the MS SDK compiler. Or an uninitialized variable?
520 CFUNCTYPE(c_int)(lambda: None)