Package ctypes
[hide private]
[frames] | no frames]

Source Code for Package ctypes

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