/Lib/ctypes/__init__.py

http://unladen-swallow.googlecode.com/ · Python · 546 lines · 380 code · 75 blank · 91 comment · 73 complexity · 09cd6a8def7b3be804fbcfd316d696a3 MD5 · raw file

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