blob: e34c646e2d11ac1b01441521018e87a545340f21 [file] [log] [blame]
Thomas Hellerbabddfc2006-03-08 19:56:54 +00001"""create and manipulate C data types in Python"""
2
Thomas Hellerbabddfc2006-03-08 19:56:54 +00003import os as _os, sys as _sys
Thomas Hellerbabddfc2006-03-08 19:56:54 +00004
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +00005__version__ = "1.1.0"
Thomas Hellerbabddfc2006-03-08 19:56:54 +00006
7from _ctypes import Union, Structure, Array
8from _ctypes import _Pointer
9from _ctypes import CFuncPtr as _CFuncPtr
10from _ctypes import __version__ as _ctypes_version
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
Thomas Hellerbabddfc2006-03-08 19:56:54 +000012from _ctypes import ArgumentError
13
14from struct import calcsize as _calcsize
15
16if __version__ != _ctypes_version:
Collin Wintera73bfee2007-08-30 03:47:13 +000017 raise Exception("Version number mismatch", __version__, _ctypes_version)
Thomas Hellerbabddfc2006-03-08 19:56:54 +000018
19if _os.name in ("nt", "ce"):
20 from _ctypes import FormatError
21
Thomas Wouters0e3f5912006-08-11 14:57:12 +000022DEFAULT_MODE = RTLD_LOCAL
23if _os.name == "posix" and _sys.platform == "darwin":
Thomas Wouters0e3f5912006-08-11 14:57:12 +000024 # On OS X 10.3, we use RTLD_GLOBAL as default mode
25 # because RTLD_LOCAL does not work at least on some
Guido van Rossum8ce8a782007-11-01 19:42:39 +000026 # libraries. OS X 10.3 is Darwin 7, so we check for
27 # that.
Thomas Wouters0e3f5912006-08-11 14:57:12 +000028
Larry Hastings605a62d2012-06-24 04:33:36 -070029 if int(_os.uname().release.split('.')[0]) < 8:
Thomas Wouters0e3f5912006-08-11 14:57:12 +000030 DEFAULT_MODE = RTLD_GLOBAL
31
Thomas Hellerbabddfc2006-03-08 19:56:54 +000032from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
Thomas Heller9cac7b62008-06-06 09:31:40 +000033 FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \
34 FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \
35 FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR
Thomas Hellerbabddfc2006-03-08 19:56:54 +000036
Victor Stinner765531d2013-03-26 01:11:54 +010037# WINOLEAPI -> HRESULT
38# WINOLEAPI_(type)
39#
40# STDMETHODCALLTYPE
41#
42# STDMETHOD(name)
43# STDMETHOD_(type, name)
44#
45# STDAPICALLTYPE
Thomas Hellerbabddfc2006-03-08 19:56:54 +000046
47def create_string_buffer(init, size=None):
Guido van Rossum97f9d4f2007-10-24 18:41:19 +000048 """create_string_buffer(aBytes) -> character array
Thomas Hellerbabddfc2006-03-08 19:56:54 +000049 create_string_buffer(anInteger) -> character array
50 create_string_buffer(aString, anInteger) -> character array
51 """
Guido van Rossum97f9d4f2007-10-24 18:41:19 +000052 if isinstance(init, (str, bytes)):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000053 if size is None:
54 size = len(init)+1
55 buftype = c_char * size
56 buf = buftype()
57 buf.value = init
58 return buf
Walter Dörwaldaa97f042007-05-03 21:05:51 +000059 elif isinstance(init, int):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000060 buftype = c_char * init
61 buf = buftype()
62 return buf
Collin Wintera73bfee2007-08-30 03:47:13 +000063 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +000064
65def c_buffer(init, size=None):
66## "deprecated, use create_string_buffer instead"
67## import warnings
68## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
69## DeprecationWarning, stacklevel=2)
70 return create_string_buffer(init, size)
71
72_c_functype_cache = {}
Thomas Heller9cac7b62008-06-06 09:31:40 +000073def CFUNCTYPE(restype, *argtypes, **kw):
74 """CFUNCTYPE(restype, *argtypes,
75 use_errno=False, use_last_error=False) -> function prototype.
Tim Peterse8d09e52006-03-09 01:15:05 +000076
Thomas Hellerbabddfc2006-03-08 19:56:54 +000077 restype: the result type
78 argtypes: a sequence specifying the argument types
Tim Peterse8d09e52006-03-09 01:15:05 +000079
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080 The function prototype can be called in different ways to create a
Thomas Hellerbabddfc2006-03-08 19:56:54 +000081 callable object:
Tim Peterse8d09e52006-03-09 01:15:05 +000082
Thomas Wouters477c8d52006-05-27 19:21:47 +000083 prototype(integer address) -> foreign function
84 prototype(callable) -> create and return a C callable function from callable
85 prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
86 prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
87 prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
Thomas Hellerbabddfc2006-03-08 19:56:54 +000088 """
Thomas Heller9cac7b62008-06-06 09:31:40 +000089 flags = _FUNCFLAG_CDECL
90 if kw.pop("use_errno", False):
91 flags |= _FUNCFLAG_USE_ERRNO
92 if kw.pop("use_last_error", False):
93 flags |= _FUNCFLAG_USE_LASTERROR
94 if kw:
95 raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
Thomas Hellerbabddfc2006-03-08 19:56:54 +000096 try:
Thomas Heller9cac7b62008-06-06 09:31:40 +000097 return _c_functype_cache[(restype, argtypes, flags)]
Thomas Hellerbabddfc2006-03-08 19:56:54 +000098 except KeyError:
99 class CFunctionType(_CFuncPtr):
100 _argtypes_ = argtypes
101 _restype_ = restype
Thomas Heller9cac7b62008-06-06 09:31:40 +0000102 _flags_ = flags
103 _c_functype_cache[(restype, argtypes, flags)] = CFunctionType
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000104 return CFunctionType
105
106if _os.name in ("nt", "ce"):
107 from _ctypes import LoadLibrary as _dlopen
108 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
109 if _os.name == "ce":
110 # 'ce' doesn't have the stdcall calling convention
111 _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
112
113 _win_functype_cache = {}
Thomas Heller9cac7b62008-06-06 09:31:40 +0000114 def WINFUNCTYPE(restype, *argtypes, **kw):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000115 # docstring set later (very similar to CFUNCTYPE.__doc__)
Thomas Heller9cac7b62008-06-06 09:31:40 +0000116 flags = _FUNCFLAG_STDCALL
117 if kw.pop("use_errno", False):
118 flags |= _FUNCFLAG_USE_ERRNO
119 if kw.pop("use_last_error", False):
120 flags |= _FUNCFLAG_USE_LASTERROR
121 if kw:
122 raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000123 try:
Thomas Heller9cac7b62008-06-06 09:31:40 +0000124 return _win_functype_cache[(restype, argtypes, flags)]
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000125 except KeyError:
126 class WinFunctionType(_CFuncPtr):
127 _argtypes_ = argtypes
128 _restype_ = restype
Thomas Heller9cac7b62008-06-06 09:31:40 +0000129 _flags_ = flags
130 _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000131 return WinFunctionType
132 if WINFUNCTYPE.__doc__:
133 WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
134
135elif _os.name == "posix":
136 from _ctypes import dlopen as _dlopen
137
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000138from _ctypes import sizeof, byref, addressof, alignment, resize
Thomas Heller9cac7b62008-06-06 09:31:40 +0000139from _ctypes import get_errno, set_errno
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000140from _ctypes import _SimpleCData
141
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000142def _check_size(typ, typecode=None):
143 # Check if sizeof(ctypes_type) against struct.calcsize. This
144 # should protect somewhat against a misconfigured libffi.
145 from struct import calcsize
146 if typecode is None:
147 # Most _type_ codes are the same as used in struct
148 typecode = typ._type_
149 actual, required = sizeof(typ), calcsize(typecode)
150 if actual != required:
151 raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
152 (typ, actual, required))
153
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000154class py_object(_SimpleCData):
155 _type_ = "O"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000156 def __repr__(self):
157 try:
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000158 return super().__repr__()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000159 except ValueError:
160 return "%s(<NULL>)" % type(self).__name__
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000161_check_size(py_object, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000162
163class c_short(_SimpleCData):
164 _type_ = "h"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000165_check_size(c_short)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000166
167class c_ushort(_SimpleCData):
168 _type_ = "H"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000169_check_size(c_ushort)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000170
171class c_long(_SimpleCData):
172 _type_ = "l"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000173_check_size(c_long)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000174
175class c_ulong(_SimpleCData):
176 _type_ = "L"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000177_check_size(c_ulong)
Tim Peterse8d09e52006-03-09 01:15:05 +0000178
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000179if _calcsize("i") == _calcsize("l"):
180 # if int and long have the same size, make c_int an alias for c_long
181 c_int = c_long
182 c_uint = c_ulong
183else:
184 class c_int(_SimpleCData):
185 _type_ = "i"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000186 _check_size(c_int)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000187
188 class c_uint(_SimpleCData):
189 _type_ = "I"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000190 _check_size(c_uint)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000191
192class c_float(_SimpleCData):
193 _type_ = "f"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000194_check_size(c_float)
Tim Peterse8d09e52006-03-09 01:15:05 +0000195
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000196class c_double(_SimpleCData):
197 _type_ = "d"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000198_check_size(c_double)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000199
Thomas Wouters89d996e2007-09-08 17:39:28 +0000200class c_longdouble(_SimpleCData):
Thomas Hellerff721222008-01-17 18:46:55 +0000201 _type_ = "g"
Thomas Wouters89d996e2007-09-08 17:39:28 +0000202if sizeof(c_longdouble) == sizeof(c_double):
203 c_longdouble = c_double
204
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000205if _calcsize("l") == _calcsize("q"):
206 # if long and long long have the same size, make c_longlong an alias for c_long
207 c_longlong = c_long
208 c_ulonglong = c_ulong
209else:
210 class c_longlong(_SimpleCData):
211 _type_ = "q"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000212 _check_size(c_longlong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000213
214 class c_ulonglong(_SimpleCData):
215 _type_ = "Q"
216 ## def from_param(cls, val):
217 ## return ('d', float(val), val)
218 ## from_param = classmethod(from_param)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000219 _check_size(c_ulonglong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000220
221class c_ubyte(_SimpleCData):
222 _type_ = "B"
223c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
224# backward compatibility:
225##c_uchar = c_ubyte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000226_check_size(c_ubyte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000227
228class c_byte(_SimpleCData):
229 _type_ = "b"
230c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000231_check_size(c_byte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000232
233class c_char(_SimpleCData):
234 _type_ = "c"
235c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000236_check_size(c_char)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000237
238class c_char_p(_SimpleCData):
239 _type_ = "z"
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000240 if _os.name == "nt":
241 def __repr__(self):
242 if not windll.kernel32.IsBadStringPtrA(self, -1):
243 return "%s(%r)" % (self.__class__.__name__, self.value)
244 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
245 else:
246 def __repr__(self):
247 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000248_check_size(c_char_p, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000249
250class c_void_p(_SimpleCData):
251 _type_ = "P"
252c_voidp = c_void_p # backwards compatibility (to a bug)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000253_check_size(c_void_p)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000254
Guido van Rossumd8faa362007-04-27 19:54:29 +0000255class c_bool(_SimpleCData):
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000256 _type_ = "?"
Guido van Rossumd8faa362007-04-27 19:54:29 +0000257
Thomas Heller3071f812008-04-14 16:17:33 +0000258from _ctypes import POINTER, pointer, _pointer_type_cache
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000259
Victor Stinnercf448832010-07-28 00:15:03 +0000260class c_wchar_p(_SimpleCData):
261 _type_ = "Z"
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000262
Victor Stinnercf448832010-07-28 00:15:03 +0000263class c_wchar(_SimpleCData):
264 _type_ = "u"
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000265
Meador Inge11e38132011-11-25 22:33:32 -0600266def _reset_cache():
267 _pointer_type_cache.clear()
268 _c_functype_cache.clear()
269 if _os.name in ("nt", "ce"):
270 _win_functype_cache.clear()
271 # _SimpleCData.c_wchar_p_from_param
272 POINTER(c_wchar).from_param = c_wchar_p.from_param
273 # _SimpleCData.c_char_p_from_param
274 POINTER(c_char).from_param = c_char_p.from_param
275 _pointer_type_cache[None] = c_void_p
276 # XXX for whatever reasons, creating the first instance of a callback
277 # function is needed for the unittests on Win64 to succeed. This MAY
278 # be a compiler bug, since the problem occurs only when _ctypes is
279 # compiled with the MS SDK compiler. Or an uninitialized variable?
280 CFUNCTYPE(c_int)(lambda: None)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000281
Victor Stinnercf448832010-07-28 00:15:03 +0000282def create_unicode_buffer(init, size=None):
283 """create_unicode_buffer(aString) -> character array
284 create_unicode_buffer(anInteger) -> character array
285 create_unicode_buffer(aString, anInteger) -> character array
286 """
287 if isinstance(init, (str, bytes)):
288 if size is None:
289 size = len(init)+1
290 buftype = c_wchar * size
291 buf = buftype()
292 buf.value = init
293 return buf
294 elif isinstance(init, int):
295 buftype = c_wchar * init
296 buf = buftype()
297 return buf
298 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000299
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000300
301# XXX Deprecated
302def SetPointerType(pointer, cls):
303 if _pointer_type_cache.get(cls, None) is not None:
Collin Wintera73bfee2007-08-30 03:47:13 +0000304 raise RuntimeError("This type already exists in the cache")
Guido van Rossum1b01e5c2006-08-19 02:45:06 +0000305 if id(pointer) not in _pointer_type_cache:
Collin Wintera73bfee2007-08-30 03:47:13 +0000306 raise RuntimeError("What's this???")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000307 pointer.set_type(cls)
308 _pointer_type_cache[cls] = pointer
309 del _pointer_type_cache[id(pointer)]
310
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000311# XXX Deprecated
312def ARRAY(typ, len):
313 return typ * len
314
315################################################################
316
317
318class CDLL(object):
319 """An instance of this class represents a loaded dll/shared
320 library, exporting functions using the standard C calling
321 convention (named 'cdecl' on Windows).
322
323 The exported functions can be accessed as attributes, or by
324 indexing with the function name. Examples:
325
326 <obj>.qsort -> callable object
327 <obj>['qsort'] -> callable object
328
329 Calling the functions releases the Python GIL during the call and
Thomas Woutersed03b412007-08-28 21:37:11 +0000330 reacquires it afterwards.
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000331 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000332 _func_flags_ = _FUNCFLAG_CDECL
333 _func_restype_ = c_int
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000334
Thomas Heller9cac7b62008-06-06 09:31:40 +0000335 def __init__(self, name, mode=DEFAULT_MODE, handle=None,
336 use_errno=False,
337 use_last_error=False):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000338 self._name = name
Thomas Heller9cac7b62008-06-06 09:31:40 +0000339 flags = self._func_flags_
340 if use_errno:
341 flags |= _FUNCFLAG_USE_ERRNO
342 if use_last_error:
343 flags |= _FUNCFLAG_USE_LASTERROR
344
345 class _FuncPtr(_CFuncPtr):
346 _flags_ = flags
347 _restype_ = self._func_restype_
348 self._FuncPtr = _FuncPtr
349
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000350 if handle is None:
351 self._handle = _dlopen(self._name, mode)
352 else:
353 self._handle = handle
354
355 def __repr__(self):
356 return "<%s '%s', handle %x at %x>" % \
357 (self.__class__.__name__, self._name,
Christian Heimesa37d4c62007-12-04 23:02:19 +0000358 (self._handle & (_sys.maxsize*2 + 1)),
359 id(self) & (_sys.maxsize*2 + 1))
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000360
361 def __getattr__(self, name):
362 if name.startswith('__') and name.endswith('__'):
Collin Wintera73bfee2007-08-30 03:47:13 +0000363 raise AttributeError(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000364 func = self.__getitem__(name)
365 setattr(self, name, func)
366 return func
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000367
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000368 def __getitem__(self, name_or_ordinal):
369 func = self._FuncPtr((name_or_ordinal, self))
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000370 if not isinstance(name_or_ordinal, int):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000371 func.__name__ = name_or_ordinal
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000372 return func
373
374class PyDLL(CDLL):
375 """This class represents the Python library itself. It allows to
376 access Python API functions. The GIL is not released, and
377 Python exceptions are handled correctly.
378 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000379 _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000380
381if _os.name in ("nt", "ce"):
Tim Peterse8d09e52006-03-09 01:15:05 +0000382
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000383 class WinDLL(CDLL):
384 """This class represents a dll exporting functions using the
385 Windows stdcall calling convention.
386 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000387 _func_flags_ = _FUNCFLAG_STDCALL
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000388
389 # XXX Hm, what about HRESULT as normal parameter?
390 # Mustn't it derive from c_long then?
391 from _ctypes import _check_HRESULT, _SimpleCData
392 class HRESULT(_SimpleCData):
393 _type_ = "l"
394 # _check_retval_ is called with the function's result when it
395 # is used as restype. It checks for the FAILED bit, and
Andrew Svetlov2606a6f2012-12-19 14:33:35 +0200396 # raises an OSError if it is set.
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000397 #
398 # The _check_retval_ method is implemented in C, so that the
399 # method definition itself is not included in the traceback
400 # when it raises an error - that is what we want (and Python
401 # doesn't have a way to raise an exception in the caller's
402 # frame).
403 _check_retval_ = _check_HRESULT
Tim Peterse8d09e52006-03-09 01:15:05 +0000404
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000405 class OleDLL(CDLL):
406 """This class represents a dll exporting functions using the
407 Windows stdcall calling convention, and returning HRESULT.
Andrew Svetlov2606a6f2012-12-19 14:33:35 +0200408 HRESULT error values are automatically raised as OSError
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000409 exceptions.
410 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000411 _func_flags_ = _FUNCFLAG_STDCALL
412 _func_restype_ = HRESULT
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000413
Thomas Wouters477c8d52006-05-27 19:21:47 +0000414class LibraryLoader(object):
415 def __init__(self, dlltype):
416 self._dlltype = dlltype
417
418 def __getattr__(self, name):
419 if name[0] == '_':
420 raise AttributeError(name)
421 dll = self._dlltype(name)
422 setattr(self, name, dll)
423 return dll
424
425 def __getitem__(self, name):
426 return getattr(self, name)
427
428 def LoadLibrary(self, name):
429 return self._dlltype(name)
430
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000431cdll = LibraryLoader(CDLL)
432pydll = LibraryLoader(PyDLL)
433
434if _os.name in ("nt", "ce"):
435 pythonapi = PyDLL("python dll", None, _sys.dllhandle)
436elif _sys.platform == "cygwin":
437 pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
438else:
439 pythonapi = PyDLL(None)
440
441
442if _os.name in ("nt", "ce"):
443 windll = LibraryLoader(WinDLL)
444 oledll = LibraryLoader(OleDLL)
445
446 if _os.name == "nt":
447 GetLastError = windll.kernel32.GetLastError
448 else:
449 GetLastError = windll.coredll.GetLastError
Thomas Heller9cac7b62008-06-06 09:31:40 +0000450 from _ctypes import get_last_error, set_last_error
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000451
452 def WinError(code=None, descr=None):
453 if code is None:
454 code = GetLastError()
455 if descr is None:
456 descr = FormatError(code).strip()
Andrew Svetlov2606a6f2012-12-19 14:33:35 +0200457 return OSError(None, descr, None, code)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000458
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000459if sizeof(c_uint) == sizeof(c_void_p):
460 c_size_t = c_uint
Gregory P. Smith1a530912010-03-01 04:59:27 +0000461 c_ssize_t = c_int
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000462elif sizeof(c_ulong) == sizeof(c_void_p):
463 c_size_t = c_ulong
Gregory P. Smith1a530912010-03-01 04:59:27 +0000464 c_ssize_t = c_long
Thomas Wouters89f507f2006-12-13 04:49:30 +0000465elif sizeof(c_ulonglong) == sizeof(c_void_p):
466 c_size_t = c_ulonglong
Gregory P. Smith1a530912010-03-01 04:59:27 +0000467 c_ssize_t = c_longlong
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000468
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000469# functions
470
471from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
472
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000473## void *memmove(void *, const void *, size_t);
474memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
475
476## void *memset(void *, int, size_t)
477memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
478
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000479def PYFUNCTYPE(restype, *argtypes):
480 class CFunctionType(_CFuncPtr):
481 _argtypes_ = argtypes
482 _restype_ = restype
483 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
484 return CFunctionType
Thomas Wouters477c8d52006-05-27 19:21:47 +0000485
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000486_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000487def cast(obj, typ):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000488 return _cast(obj, obj, typ)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000489
Thomas Heller47bc8092008-08-19 06:38:12 +0000490_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000491def string_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000492 """string_at(addr[, size]) -> string
493
494 Return the string at addr."""
495 return _string_at(ptr, size)
496
497try:
498 from _ctypes import _wstring_at_addr
499except ImportError:
500 pass
501else:
Thomas Heller47bc8092008-08-19 06:38:12 +0000502 _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000503 def wstring_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000504 """wstring_at(addr[, size]) -> string
505
506 Return the string at addr."""
507 return _wstring_at(ptr, size)
Tim Peterse8d09e52006-03-09 01:15:05 +0000508
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000509
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000510if _os.name in ("nt", "ce"): # COM stuff
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000511 def DllGetClassObject(rclsid, riid, ppv):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000512 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000513 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000514 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000515 return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000516 else:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000517 return ccom.DllGetClassObject(rclsid, riid, ppv)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000518
519 def DllCanUnloadNow():
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000520 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000521 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000522 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000523 return 0 # S_OK
524 return ccom.DllCanUnloadNow()
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000525
526from ctypes._endian import BigEndianStructure, LittleEndianStructure
527
528# Fill in specifically-sized types
529c_int8 = c_byte
530c_uint8 = c_ubyte
531for kind in [c_short, c_int, c_long, c_longlong]:
532 if sizeof(kind) == 2: c_int16 = kind
533 elif sizeof(kind) == 4: c_int32 = kind
534 elif sizeof(kind) == 8: c_int64 = kind
535for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
536 if sizeof(kind) == 2: c_uint16 = kind
537 elif sizeof(kind) == 4: c_uint32 = kind
538 elif sizeof(kind) == 8: c_uint64 = kind
539del(kind)
Thomas Heller674e9382007-08-31 13:06:44 +0000540
Meador Inge11e38132011-11-25 22:33:32 -0600541_reset_cache()