blob: 4cb6d0de27104b8dfb7e3208d626d4393f41e158 [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 """
Serhiy Storchaka4f06d602014-08-09 09:33:05 +030052 if isinstance(init, 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"
Steve Dowere6bb7eb2015-03-25 21:58:36 -0700240 def __repr__(self):
241 return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000242_check_size(c_char_p, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000243
244class c_void_p(_SimpleCData):
245 _type_ = "P"
246c_voidp = c_void_p # backwards compatibility (to a bug)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000247_check_size(c_void_p)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000248
Guido van Rossumd8faa362007-04-27 19:54:29 +0000249class c_bool(_SimpleCData):
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000250 _type_ = "?"
Guido van Rossumd8faa362007-04-27 19:54:29 +0000251
Thomas Heller3071f812008-04-14 16:17:33 +0000252from _ctypes import POINTER, pointer, _pointer_type_cache
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000253
Victor Stinnercf448832010-07-28 00:15:03 +0000254class c_wchar_p(_SimpleCData):
255 _type_ = "Z"
Steve Dowere6bb7eb2015-03-25 21:58:36 -0700256 def __repr__(self):
257 return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000258
Victor Stinnercf448832010-07-28 00:15:03 +0000259class c_wchar(_SimpleCData):
260 _type_ = "u"
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000261
Meador Inge11e38132011-11-25 22:33:32 -0600262def _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)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000277
Victor Stinnercf448832010-07-28 00:15:03 +0000278def create_unicode_buffer(init, size=None):
279 """create_unicode_buffer(aString) -> character array
280 create_unicode_buffer(anInteger) -> character array
281 create_unicode_buffer(aString, anInteger) -> character array
282 """
Serhiy Storchaka4f06d602014-08-09 09:33:05 +0300283 if isinstance(init, str):
Victor Stinnercf448832010-07-28 00:15:03 +0000284 if size is None:
285 size = len(init)+1
286 buftype = c_wchar * size
287 buf = buftype()
288 buf.value = init
289 return buf
290 elif isinstance(init, int):
291 buftype = c_wchar * init
292 buf = buftype()
293 return buf
294 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000295
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000296
297# XXX Deprecated
298def SetPointerType(pointer, cls):
299 if _pointer_type_cache.get(cls, None) is not None:
Collin Wintera73bfee2007-08-30 03:47:13 +0000300 raise RuntimeError("This type already exists in the cache")
Guido van Rossum1b01e5c2006-08-19 02:45:06 +0000301 if id(pointer) not in _pointer_type_cache:
Collin Wintera73bfee2007-08-30 03:47:13 +0000302 raise RuntimeError("What's this???")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000303 pointer.set_type(cls)
304 _pointer_type_cache[cls] = pointer
305 del _pointer_type_cache[id(pointer)]
306
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000307# XXX Deprecated
308def ARRAY(typ, len):
309 return typ * len
310
311################################################################
312
313
314class CDLL(object):
315 """An instance of this class represents a loaded dll/shared
316 library, exporting functions using the standard C calling
317 convention (named 'cdecl' on Windows).
318
319 The exported functions can be accessed as attributes, or by
320 indexing with the function name. Examples:
321
322 <obj>.qsort -> callable object
323 <obj>['qsort'] -> callable object
324
325 Calling the functions releases the Python GIL during the call and
Thomas Woutersed03b412007-08-28 21:37:11 +0000326 reacquires it afterwards.
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000327 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000328 _func_flags_ = _FUNCFLAG_CDECL
329 _func_restype_ = c_int
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000330
Thomas Heller9cac7b62008-06-06 09:31:40 +0000331 def __init__(self, name, mode=DEFAULT_MODE, handle=None,
332 use_errno=False,
333 use_last_error=False):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000334 self._name = name
Thomas Heller9cac7b62008-06-06 09:31:40 +0000335 flags = self._func_flags_
336 if use_errno:
337 flags |= _FUNCFLAG_USE_ERRNO
338 if use_last_error:
339 flags |= _FUNCFLAG_USE_LASTERROR
340
341 class _FuncPtr(_CFuncPtr):
342 _flags_ = flags
343 _restype_ = self._func_restype_
344 self._FuncPtr = _FuncPtr
345
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000346 if handle is None:
347 self._handle = _dlopen(self._name, mode)
348 else:
349 self._handle = handle
350
351 def __repr__(self):
Serhiy Storchaka0c937b32014-07-22 12:14:52 +0300352 return "<%s '%s', handle %x at %#x>" % \
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000353 (self.__class__.__name__, self._name,
Christian Heimesa37d4c62007-12-04 23:02:19 +0000354 (self._handle & (_sys.maxsize*2 + 1)),
355 id(self) & (_sys.maxsize*2 + 1))
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000356
357 def __getattr__(self, name):
358 if name.startswith('__') and name.endswith('__'):
Collin Wintera73bfee2007-08-30 03:47:13 +0000359 raise AttributeError(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000360 func = self.__getitem__(name)
361 setattr(self, name, func)
362 return func
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000363
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000364 def __getitem__(self, name_or_ordinal):
365 func = self._FuncPtr((name_or_ordinal, self))
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000366 if not isinstance(name_or_ordinal, int):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000367 func.__name__ = name_or_ordinal
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000368 return func
369
370class PyDLL(CDLL):
371 """This class represents the Python library itself. It allows to
372 access Python API functions. The GIL is not released, and
373 Python exceptions are handled correctly.
374 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000375 _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000376
377if _os.name in ("nt", "ce"):
Tim Peterse8d09e52006-03-09 01:15:05 +0000378
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000379 class WinDLL(CDLL):
380 """This class represents a dll exporting functions using the
381 Windows stdcall calling convention.
382 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000383 _func_flags_ = _FUNCFLAG_STDCALL
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000384
385 # XXX Hm, what about HRESULT as normal parameter?
386 # Mustn't it derive from c_long then?
387 from _ctypes import _check_HRESULT, _SimpleCData
388 class HRESULT(_SimpleCData):
389 _type_ = "l"
390 # _check_retval_ is called with the function's result when it
391 # is used as restype. It checks for the FAILED bit, and
Andrew Svetlov2606a6f2012-12-19 14:33:35 +0200392 # raises an OSError if it is set.
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000393 #
394 # The _check_retval_ method is implemented in C, so that the
395 # method definition itself is not included in the traceback
396 # when it raises an error - that is what we want (and Python
397 # doesn't have a way to raise an exception in the caller's
398 # frame).
399 _check_retval_ = _check_HRESULT
Tim Peterse8d09e52006-03-09 01:15:05 +0000400
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000401 class OleDLL(CDLL):
402 """This class represents a dll exporting functions using the
403 Windows stdcall calling convention, and returning HRESULT.
Andrew Svetlov2606a6f2012-12-19 14:33:35 +0200404 HRESULT error values are automatically raised as OSError
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000405 exceptions.
406 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000407 _func_flags_ = _FUNCFLAG_STDCALL
408 _func_restype_ = HRESULT
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000409
Thomas Wouters477c8d52006-05-27 19:21:47 +0000410class LibraryLoader(object):
411 def __init__(self, dlltype):
412 self._dlltype = dlltype
413
414 def __getattr__(self, name):
415 if name[0] == '_':
416 raise AttributeError(name)
417 dll = self._dlltype(name)
418 setattr(self, name, dll)
419 return dll
420
421 def __getitem__(self, name):
422 return getattr(self, name)
423
424 def LoadLibrary(self, name):
425 return self._dlltype(name)
426
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000427cdll = LibraryLoader(CDLL)
428pydll = LibraryLoader(PyDLL)
429
430if _os.name in ("nt", "ce"):
431 pythonapi = PyDLL("python dll", None, _sys.dllhandle)
432elif _sys.platform == "cygwin":
433 pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
434else:
435 pythonapi = PyDLL(None)
436
437
438if _os.name in ("nt", "ce"):
439 windll = LibraryLoader(WinDLL)
440 oledll = LibraryLoader(OleDLL)
441
442 if _os.name == "nt":
443 GetLastError = windll.kernel32.GetLastError
444 else:
445 GetLastError = windll.coredll.GetLastError
Thomas Heller9cac7b62008-06-06 09:31:40 +0000446 from _ctypes import get_last_error, set_last_error
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000447
448 def WinError(code=None, descr=None):
449 if code is None:
450 code = GetLastError()
451 if descr is None:
452 descr = FormatError(code).strip()
Andrew Svetlov2606a6f2012-12-19 14:33:35 +0200453 return OSError(None, descr, None, code)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000454
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000455if sizeof(c_uint) == sizeof(c_void_p):
456 c_size_t = c_uint
Gregory P. Smith1a530912010-03-01 04:59:27 +0000457 c_ssize_t = c_int
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000458elif sizeof(c_ulong) == sizeof(c_void_p):
459 c_size_t = c_ulong
Gregory P. Smith1a530912010-03-01 04:59:27 +0000460 c_ssize_t = c_long
Thomas Wouters89f507f2006-12-13 04:49:30 +0000461elif sizeof(c_ulonglong) == sizeof(c_void_p):
462 c_size_t = c_ulonglong
Gregory P. Smith1a530912010-03-01 04:59:27 +0000463 c_ssize_t = c_longlong
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000464
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000465# functions
466
467from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
468
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000469## void *memmove(void *, const void *, size_t);
470memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
471
472## void *memset(void *, int, size_t)
473memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
474
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000475def PYFUNCTYPE(restype, *argtypes):
476 class CFunctionType(_CFuncPtr):
477 _argtypes_ = argtypes
478 _restype_ = restype
479 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
480 return CFunctionType
Thomas Wouters477c8d52006-05-27 19:21:47 +0000481
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000482_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000483def cast(obj, typ):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000484 return _cast(obj, obj, typ)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000485
Thomas Heller47bc8092008-08-19 06:38:12 +0000486_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000487def string_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000488 """string_at(addr[, size]) -> string
489
490 Return the string at addr."""
491 return _string_at(ptr, size)
492
493try:
494 from _ctypes import _wstring_at_addr
495except ImportError:
496 pass
497else:
Thomas Heller47bc8092008-08-19 06:38:12 +0000498 _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000499 def wstring_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000500 """wstring_at(addr[, size]) -> string
501
502 Return the string at addr."""
503 return _wstring_at(ptr, size)
Tim Peterse8d09e52006-03-09 01:15:05 +0000504
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000505
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000506if _os.name in ("nt", "ce"): # COM stuff
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000507 def DllGetClassObject(rclsid, riid, ppv):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000508 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000509 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000510 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000511 return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000512 else:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000513 return ccom.DllGetClassObject(rclsid, riid, ppv)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000514
515 def DllCanUnloadNow():
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000516 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000517 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000518 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519 return 0 # S_OK
520 return ccom.DllCanUnloadNow()
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000521
522from ctypes._endian import BigEndianStructure, LittleEndianStructure
523
524# Fill in specifically-sized types
525c_int8 = c_byte
526c_uint8 = c_ubyte
527for kind in [c_short, c_int, c_long, c_longlong]:
528 if sizeof(kind) == 2: c_int16 = kind
529 elif sizeof(kind) == 4: c_int32 = kind
530 elif sizeof(kind) == 8: c_int64 = kind
531for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
532 if sizeof(kind) == 2: c_uint16 = kind
533 elif sizeof(kind) == 4: c_uint32 = kind
534 elif sizeof(kind) == 8: c_uint64 = kind
535del(kind)
Thomas Heller674e9382007-08-31 13:06:44 +0000536
Meador Inge11e38132011-11-25 22:33:32 -0600537_reset_cache()