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