blob: 614677398864821711d3606a200f4a783e209aa7 [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
Larry Hastings10108a72016-09-05 15:11:23 -070019if _os.name == "nt":
Thomas Hellerbabddfc2006-03-08 19:56:54 +000020 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
Ezio Melottiee2a3922016-01-09 16:08:24 +020050 create_string_buffer(aBytes, anInteger) -> character array
Thomas Hellerbabddfc2006-03-08 19:56:54 +000051 """
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
Larry Hastings10108a72016-09-05 15:11:23 -0700106if _os.name == "nt":
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000107 from _ctypes import LoadLibrary as _dlopen
108 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000109
110 _win_functype_cache = {}
Thomas Heller9cac7b62008-06-06 09:31:40 +0000111 def WINFUNCTYPE(restype, *argtypes, **kw):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000112 # docstring set later (very similar to CFUNCTYPE.__doc__)
Thomas Heller9cac7b62008-06-06 09:31:40 +0000113 flags = _FUNCFLAG_STDCALL
114 if kw.pop("use_errno", False):
115 flags |= _FUNCFLAG_USE_ERRNO
116 if kw.pop("use_last_error", False):
117 flags |= _FUNCFLAG_USE_LASTERROR
118 if kw:
119 raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000120 try:
Thomas Heller9cac7b62008-06-06 09:31:40 +0000121 return _win_functype_cache[(restype, argtypes, flags)]
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000122 except KeyError:
123 class WinFunctionType(_CFuncPtr):
124 _argtypes_ = argtypes
125 _restype_ = restype
Thomas Heller9cac7b62008-06-06 09:31:40 +0000126 _flags_ = flags
127 _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000128 return WinFunctionType
129 if WINFUNCTYPE.__doc__:
130 WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
131
132elif _os.name == "posix":
133 from _ctypes import dlopen as _dlopen
134
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000135from _ctypes import sizeof, byref, addressof, alignment, resize
Thomas Heller9cac7b62008-06-06 09:31:40 +0000136from _ctypes import get_errno, set_errno
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000137from _ctypes import _SimpleCData
138
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000139def _check_size(typ, typecode=None):
140 # Check if sizeof(ctypes_type) against struct.calcsize. This
141 # should protect somewhat against a misconfigured libffi.
142 from struct import calcsize
143 if typecode is None:
144 # Most _type_ codes are the same as used in struct
145 typecode = typ._type_
146 actual, required = sizeof(typ), calcsize(typecode)
147 if actual != required:
148 raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
149 (typ, actual, required))
150
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000151class py_object(_SimpleCData):
152 _type_ = "O"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000153 def __repr__(self):
154 try:
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000155 return super().__repr__()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000156 except ValueError:
157 return "%s(<NULL>)" % type(self).__name__
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000158_check_size(py_object, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000159
160class c_short(_SimpleCData):
161 _type_ = "h"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000162_check_size(c_short)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000163
164class c_ushort(_SimpleCData):
165 _type_ = "H"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000166_check_size(c_ushort)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000167
168class c_long(_SimpleCData):
169 _type_ = "l"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000170_check_size(c_long)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000171
172class c_ulong(_SimpleCData):
173 _type_ = "L"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000174_check_size(c_ulong)
Tim Peterse8d09e52006-03-09 01:15:05 +0000175
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000176if _calcsize("i") == _calcsize("l"):
177 # if int and long have the same size, make c_int an alias for c_long
178 c_int = c_long
179 c_uint = c_ulong
180else:
181 class c_int(_SimpleCData):
182 _type_ = "i"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000183 _check_size(c_int)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000184
185 class c_uint(_SimpleCData):
186 _type_ = "I"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000187 _check_size(c_uint)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000188
189class c_float(_SimpleCData):
190 _type_ = "f"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000191_check_size(c_float)
Tim Peterse8d09e52006-03-09 01:15:05 +0000192
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000193class c_double(_SimpleCData):
194 _type_ = "d"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000195_check_size(c_double)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000196
Thomas Wouters89d996e2007-09-08 17:39:28 +0000197class c_longdouble(_SimpleCData):
Thomas Hellerff721222008-01-17 18:46:55 +0000198 _type_ = "g"
Thomas Wouters89d996e2007-09-08 17:39:28 +0000199if sizeof(c_longdouble) == sizeof(c_double):
200 c_longdouble = c_double
201
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000202if _calcsize("l") == _calcsize("q"):
203 # if long and long long have the same size, make c_longlong an alias for c_long
204 c_longlong = c_long
205 c_ulonglong = c_ulong
206else:
207 class c_longlong(_SimpleCData):
208 _type_ = "q"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000209 _check_size(c_longlong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000210
211 class c_ulonglong(_SimpleCData):
212 _type_ = "Q"
213 ## def from_param(cls, val):
214 ## return ('d', float(val), val)
215 ## from_param = classmethod(from_param)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000216 _check_size(c_ulonglong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000217
218class c_ubyte(_SimpleCData):
219 _type_ = "B"
220c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
221# backward compatibility:
222##c_uchar = c_ubyte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000223_check_size(c_ubyte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000224
225class c_byte(_SimpleCData):
226 _type_ = "b"
227c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000228_check_size(c_byte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000229
230class c_char(_SimpleCData):
231 _type_ = "c"
232c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000233_check_size(c_char)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000234
235class c_char_p(_SimpleCData):
236 _type_ = "z"
Steve Dowere6bb7eb2015-03-25 21:58:36 -0700237 def __repr__(self):
238 return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000239_check_size(c_char_p, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000240
241class c_void_p(_SimpleCData):
242 _type_ = "P"
243c_voidp = c_void_p # backwards compatibility (to a bug)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000244_check_size(c_void_p)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000245
Guido van Rossumd8faa362007-04-27 19:54:29 +0000246class c_bool(_SimpleCData):
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000247 _type_ = "?"
Guido van Rossumd8faa362007-04-27 19:54:29 +0000248
Thomas Heller3071f812008-04-14 16:17:33 +0000249from _ctypes import POINTER, pointer, _pointer_type_cache
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000250
Victor Stinnercf448832010-07-28 00:15:03 +0000251class c_wchar_p(_SimpleCData):
252 _type_ = "Z"
Steve Dowere6bb7eb2015-03-25 21:58:36 -0700253 def __repr__(self):
254 return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000255
Victor Stinnercf448832010-07-28 00:15:03 +0000256class c_wchar(_SimpleCData):
257 _type_ = "u"
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000258
Meador Inge11e38132011-11-25 22:33:32 -0600259def _reset_cache():
260 _pointer_type_cache.clear()
261 _c_functype_cache.clear()
Larry Hastings10108a72016-09-05 15:11:23 -0700262 if _os.name == "nt":
Meador Inge11e38132011-11-25 22:33:32 -0600263 _win_functype_cache.clear()
264 # _SimpleCData.c_wchar_p_from_param
265 POINTER(c_wchar).from_param = c_wchar_p.from_param
266 # _SimpleCData.c_char_p_from_param
267 POINTER(c_char).from_param = c_char_p.from_param
268 _pointer_type_cache[None] = c_void_p
269 # XXX for whatever reasons, creating the first instance of a callback
270 # function is needed for the unittests on Win64 to succeed. This MAY
271 # be a compiler bug, since the problem occurs only when _ctypes is
272 # compiled with the MS SDK compiler. Or an uninitialized variable?
273 CFUNCTYPE(c_int)(lambda: None)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000274
Victor Stinnercf448832010-07-28 00:15:03 +0000275def create_unicode_buffer(init, size=None):
276 """create_unicode_buffer(aString) -> character array
277 create_unicode_buffer(anInteger) -> character array
278 create_unicode_buffer(aString, anInteger) -> character array
279 """
Serhiy Storchaka4f06d602014-08-09 09:33:05 +0300280 if isinstance(init, str):
Victor Stinnercf448832010-07-28 00:15:03 +0000281 if size is None:
282 size = len(init)+1
283 buftype = c_wchar * size
284 buf = buftype()
285 buf.value = init
286 return buf
287 elif isinstance(init, int):
288 buftype = c_wchar * init
289 buf = buftype()
290 return buf
291 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000292
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000293
294# XXX Deprecated
295def SetPointerType(pointer, cls):
296 if _pointer_type_cache.get(cls, None) is not None:
Collin Wintera73bfee2007-08-30 03:47:13 +0000297 raise RuntimeError("This type already exists in the cache")
Guido van Rossum1b01e5c2006-08-19 02:45:06 +0000298 if id(pointer) not in _pointer_type_cache:
Collin Wintera73bfee2007-08-30 03:47:13 +0000299 raise RuntimeError("What's this???")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000300 pointer.set_type(cls)
301 _pointer_type_cache[cls] = pointer
302 del _pointer_type_cache[id(pointer)]
303
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000304# XXX Deprecated
305def ARRAY(typ, len):
306 return typ * len
307
308################################################################
309
310
311class CDLL(object):
312 """An instance of this class represents a loaded dll/shared
313 library, exporting functions using the standard C calling
314 convention (named 'cdecl' on Windows).
315
316 The exported functions can be accessed as attributes, or by
317 indexing with the function name. Examples:
318
319 <obj>.qsort -> callable object
320 <obj>['qsort'] -> callable object
321
322 Calling the functions releases the Python GIL during the call and
Thomas Woutersed03b412007-08-28 21:37:11 +0000323 reacquires it afterwards.
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000324 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000325 _func_flags_ = _FUNCFLAG_CDECL
326 _func_restype_ = c_int
Serhiy Storchaka4b318f82017-01-13 09:37:56 +0200327 # default values for repr
328 _name = '<uninitialized>'
329 _handle = 0
330 _FuncPtr = None
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000331
Thomas Heller9cac7b62008-06-06 09:31:40 +0000332 def __init__(self, name, mode=DEFAULT_MODE, handle=None,
333 use_errno=False,
334 use_last_error=False):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000335 self._name = name
Thomas Heller9cac7b62008-06-06 09:31:40 +0000336 flags = self._func_flags_
337 if use_errno:
338 flags |= _FUNCFLAG_USE_ERRNO
339 if use_last_error:
340 flags |= _FUNCFLAG_USE_LASTERROR
Michael Feltc5ae1692017-12-19 13:58:49 +0100341 if _sys.platform.startswith("aix"):
342 """When the name contains ".a(" and ends with ")",
343 e.g., "libFOO.a(libFOO.so)" - this is taken to be an
344 archive(member) syntax for dlopen(), and the mode is adjusted.
345 Otherwise, name is presented to dlopen() as a file argument.
346 """
347 if name and name.endswith(")") and ".a(" in name:
348 mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW )
Thomas Heller9cac7b62008-06-06 09:31:40 +0000349
350 class _FuncPtr(_CFuncPtr):
351 _flags_ = flags
352 _restype_ = self._func_restype_
353 self._FuncPtr = _FuncPtr
354
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000355 if handle is None:
356 self._handle = _dlopen(self._name, mode)
357 else:
358 self._handle = handle
359
360 def __repr__(self):
Serhiy Storchaka0c937b32014-07-22 12:14:52 +0300361 return "<%s '%s', handle %x at %#x>" % \
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000362 (self.__class__.__name__, self._name,
Christian Heimesa37d4c62007-12-04 23:02:19 +0000363 (self._handle & (_sys.maxsize*2 + 1)),
364 id(self) & (_sys.maxsize*2 + 1))
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000365
366 def __getattr__(self, name):
367 if name.startswith('__') and name.endswith('__'):
Collin Wintera73bfee2007-08-30 03:47:13 +0000368 raise AttributeError(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000369 func = self.__getitem__(name)
370 setattr(self, name, func)
371 return func
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000372
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000373 def __getitem__(self, name_or_ordinal):
374 func = self._FuncPtr((name_or_ordinal, self))
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000375 if not isinstance(name_or_ordinal, int):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000376 func.__name__ = name_or_ordinal
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000377 return func
378
379class PyDLL(CDLL):
Martin Panterc04fb562016-02-10 05:44:01 +0000380 """This class represents the Python library itself. It allows
381 accessing Python API functions. The GIL is not released, and
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000382 Python exceptions are handled correctly.
383 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000384 _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000385
Larry Hastings10108a72016-09-05 15:11:23 -0700386if _os.name == "nt":
Tim Peterse8d09e52006-03-09 01:15:05 +0000387
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000388 class WinDLL(CDLL):
389 """This class represents a dll exporting functions using the
390 Windows stdcall calling convention.
391 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000392 _func_flags_ = _FUNCFLAG_STDCALL
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000393
394 # XXX Hm, what about HRESULT as normal parameter?
395 # Mustn't it derive from c_long then?
396 from _ctypes import _check_HRESULT, _SimpleCData
397 class HRESULT(_SimpleCData):
398 _type_ = "l"
399 # _check_retval_ is called with the function's result when it
400 # is used as restype. It checks for the FAILED bit, and
Andrew Svetlov2606a6f2012-12-19 14:33:35 +0200401 # raises an OSError if it is set.
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000402 #
403 # The _check_retval_ method is implemented in C, so that the
404 # method definition itself is not included in the traceback
405 # when it raises an error - that is what we want (and Python
406 # doesn't have a way to raise an exception in the caller's
407 # frame).
408 _check_retval_ = _check_HRESULT
Tim Peterse8d09e52006-03-09 01:15:05 +0000409
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000410 class OleDLL(CDLL):
411 """This class represents a dll exporting functions using the
412 Windows stdcall calling convention, and returning HRESULT.
Andrew Svetlov2606a6f2012-12-19 14:33:35 +0200413 HRESULT error values are automatically raised as OSError
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000414 exceptions.
415 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000416 _func_flags_ = _FUNCFLAG_STDCALL
417 _func_restype_ = HRESULT
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000418
Thomas Wouters477c8d52006-05-27 19:21:47 +0000419class LibraryLoader(object):
420 def __init__(self, dlltype):
421 self._dlltype = dlltype
422
423 def __getattr__(self, name):
424 if name[0] == '_':
425 raise AttributeError(name)
426 dll = self._dlltype(name)
427 setattr(self, name, dll)
428 return dll
429
430 def __getitem__(self, name):
431 return getattr(self, name)
432
433 def LoadLibrary(self, name):
434 return self._dlltype(name)
435
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000436cdll = LibraryLoader(CDLL)
437pydll = LibraryLoader(PyDLL)
438
Larry Hastings10108a72016-09-05 15:11:23 -0700439if _os.name == "nt":
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000440 pythonapi = PyDLL("python dll", None, _sys.dllhandle)
441elif _sys.platform == "cygwin":
442 pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
443else:
444 pythonapi = PyDLL(None)
445
446
Larry Hastings10108a72016-09-05 15:11:23 -0700447if _os.name == "nt":
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000448 windll = LibraryLoader(WinDLL)
449 oledll = LibraryLoader(OleDLL)
450
Alex Gaynorcb760292017-08-30 07:43:14 -0400451 GetLastError = windll.kernel32.GetLastError
Thomas Heller9cac7b62008-06-06 09:31:40 +0000452 from _ctypes import get_last_error, set_last_error
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000453
454 def WinError(code=None, descr=None):
455 if code is None:
456 code = GetLastError()
457 if descr is None:
458 descr = FormatError(code).strip()
Andrew Svetlov2606a6f2012-12-19 14:33:35 +0200459 return OSError(None, descr, None, code)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000460
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000461if sizeof(c_uint) == sizeof(c_void_p):
462 c_size_t = c_uint
Gregory P. Smith1a530912010-03-01 04:59:27 +0000463 c_ssize_t = c_int
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000464elif sizeof(c_ulong) == sizeof(c_void_p):
465 c_size_t = c_ulong
Gregory P. Smith1a530912010-03-01 04:59:27 +0000466 c_ssize_t = c_long
Thomas Wouters89f507f2006-12-13 04:49:30 +0000467elif sizeof(c_ulonglong) == sizeof(c_void_p):
468 c_size_t = c_ulonglong
Gregory P. Smith1a530912010-03-01 04:59:27 +0000469 c_ssize_t = c_longlong
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000470
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000471# functions
472
473from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
474
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000475## void *memmove(void *, const void *, size_t);
476memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
477
478## void *memset(void *, int, size_t)
479memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
480
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000481def PYFUNCTYPE(restype, *argtypes):
482 class CFunctionType(_CFuncPtr):
483 _argtypes_ = argtypes
484 _restype_ = restype
485 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
486 return CFunctionType
Thomas Wouters477c8d52006-05-27 19:21:47 +0000487
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000488_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000489def cast(obj, typ):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000490 return _cast(obj, obj, typ)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000491
Thomas Heller47bc8092008-08-19 06:38:12 +0000492_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000493def string_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000494 """string_at(addr[, size]) -> string
495
496 Return the string at addr."""
497 return _string_at(ptr, size)
498
499try:
500 from _ctypes import _wstring_at_addr
501except ImportError:
502 pass
503else:
Thomas Heller47bc8092008-08-19 06:38:12 +0000504 _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000505 def wstring_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000506 """wstring_at(addr[, size]) -> string
507
508 Return the string at addr."""
509 return _wstring_at(ptr, size)
Tim Peterse8d09e52006-03-09 01:15:05 +0000510
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000511
Larry Hastings10108a72016-09-05 15:11:23 -0700512if _os.name == "nt": # COM stuff
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000513 def DllGetClassObject(rclsid, riid, ppv):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000514 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000515 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000516 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000517 return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000518 else:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519 return ccom.DllGetClassObject(rclsid, riid, ppv)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000520
521 def DllCanUnloadNow():
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000522 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000523 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000524 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000525 return 0 # S_OK
526 return ccom.DllCanUnloadNow()
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000527
528from ctypes._endian import BigEndianStructure, LittleEndianStructure
529
530# Fill in specifically-sized types
531c_int8 = c_byte
532c_uint8 = c_ubyte
533for kind in [c_short, c_int, c_long, c_longlong]:
534 if sizeof(kind) == 2: c_int16 = kind
535 elif sizeof(kind) == 4: c_int32 = kind
536 elif sizeof(kind) == 8: c_int64 = kind
537for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
538 if sizeof(kind) == 2: c_uint16 = kind
539 elif sizeof(kind) == 4: c_uint32 = kind
540 elif sizeof(kind) == 8: c_uint64 = kind
541del(kind)
Thomas Heller674e9382007-08-31 13:06:44 +0000542
Meador Inge11e38132011-11-25 22:33:32 -0600543_reset_cache()