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