blob: c92e130976bc88bb308604e105fb02db01ae6b63 [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
Thomas Hellerbabddfc2006-03-08 19:56:54 +000037"""
38WINOLEAPI -> HRESULT
39WINOLEAPI_(type)
40
41STDMETHODCALLTYPE
42
43STDMETHOD(name)
44STDMETHOD_(type, name)
45
46STDAPICALLTYPE
47"""
48
49def create_string_buffer(init, size=None):
Guido van Rossum97f9d4f2007-10-24 18:41:19 +000050 """create_string_buffer(aBytes) -> character array
Thomas Hellerbabddfc2006-03-08 19:56:54 +000051 create_string_buffer(anInteger) -> character array
52 create_string_buffer(aString, anInteger) -> character array
53 """
Guido van Rossum97f9d4f2007-10-24 18:41:19 +000054 if isinstance(init, (str, bytes)):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000055 if size is None:
56 size = len(init)+1
57 buftype = c_char * size
58 buf = buftype()
59 buf.value = init
60 return buf
Walter Dörwaldaa97f042007-05-03 21:05:51 +000061 elif isinstance(init, int):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000062 buftype = c_char * init
63 buf = buftype()
64 return buf
Collin Wintera73bfee2007-08-30 03:47:13 +000065 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +000066
67def c_buffer(init, size=None):
68## "deprecated, use create_string_buffer instead"
69## import warnings
70## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
71## DeprecationWarning, stacklevel=2)
72 return create_string_buffer(init, size)
73
74_c_functype_cache = {}
Thomas Heller9cac7b62008-06-06 09:31:40 +000075def CFUNCTYPE(restype, *argtypes, **kw):
76 """CFUNCTYPE(restype, *argtypes,
77 use_errno=False, use_last_error=False) -> function prototype.
Tim Peterse8d09e52006-03-09 01:15:05 +000078
Thomas Hellerbabddfc2006-03-08 19:56:54 +000079 restype: the result type
80 argtypes: a sequence specifying the argument types
Tim Peterse8d09e52006-03-09 01:15:05 +000081
Thomas Wouters0e3f5912006-08-11 14:57:12 +000082 The function prototype can be called in different ways to create a
Thomas Hellerbabddfc2006-03-08 19:56:54 +000083 callable object:
Tim Peterse8d09e52006-03-09 01:15:05 +000084
Thomas Wouters477c8d52006-05-27 19:21:47 +000085 prototype(integer address) -> foreign function
86 prototype(callable) -> create and return a C callable function from callable
87 prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
88 prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
89 prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
Thomas Hellerbabddfc2006-03-08 19:56:54 +000090 """
Thomas Heller9cac7b62008-06-06 09:31:40 +000091 flags = _FUNCFLAG_CDECL
92 if kw.pop("use_errno", False):
93 flags |= _FUNCFLAG_USE_ERRNO
94 if kw.pop("use_last_error", False):
95 flags |= _FUNCFLAG_USE_LASTERROR
96 if kw:
97 raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
Thomas Hellerbabddfc2006-03-08 19:56:54 +000098 try:
Thomas Heller9cac7b62008-06-06 09:31:40 +000099 return _c_functype_cache[(restype, argtypes, flags)]
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000100 except KeyError:
101 class CFunctionType(_CFuncPtr):
102 _argtypes_ = argtypes
103 _restype_ = restype
Thomas Heller9cac7b62008-06-06 09:31:40 +0000104 _flags_ = flags
105 _c_functype_cache[(restype, argtypes, flags)] = CFunctionType
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000106 return CFunctionType
107
108if _os.name in ("nt", "ce"):
109 from _ctypes import LoadLibrary as _dlopen
110 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
111 if _os.name == "ce":
112 # 'ce' doesn't have the stdcall calling convention
113 _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
114
115 _win_functype_cache = {}
Thomas Heller9cac7b62008-06-06 09:31:40 +0000116 def WINFUNCTYPE(restype, *argtypes, **kw):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000117 # docstring set later (very similar to CFUNCTYPE.__doc__)
Thomas Heller9cac7b62008-06-06 09:31:40 +0000118 flags = _FUNCFLAG_STDCALL
119 if kw.pop("use_errno", False):
120 flags |= _FUNCFLAG_USE_ERRNO
121 if kw.pop("use_last_error", False):
122 flags |= _FUNCFLAG_USE_LASTERROR
123 if kw:
124 raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000125 try:
Thomas Heller9cac7b62008-06-06 09:31:40 +0000126 return _win_functype_cache[(restype, argtypes, flags)]
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000127 except KeyError:
128 class WinFunctionType(_CFuncPtr):
129 _argtypes_ = argtypes
130 _restype_ = restype
Thomas Heller9cac7b62008-06-06 09:31:40 +0000131 _flags_ = flags
132 _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000133 return WinFunctionType
134 if WINFUNCTYPE.__doc__:
135 WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
136
137elif _os.name == "posix":
138 from _ctypes import dlopen as _dlopen
139
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000140from _ctypes import sizeof, byref, addressof, alignment, resize
Thomas Heller9cac7b62008-06-06 09:31:40 +0000141from _ctypes import get_errno, set_errno
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000142from _ctypes import _SimpleCData
143
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000144def _check_size(typ, typecode=None):
145 # Check if sizeof(ctypes_type) against struct.calcsize. This
146 # should protect somewhat against a misconfigured libffi.
147 from struct import calcsize
148 if typecode is None:
149 # Most _type_ codes are the same as used in struct
150 typecode = typ._type_
151 actual, required = sizeof(typ), calcsize(typecode)
152 if actual != required:
153 raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
154 (typ, actual, required))
155
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000156class py_object(_SimpleCData):
157 _type_ = "O"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000158 def __repr__(self):
159 try:
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000160 return super().__repr__()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000161 except ValueError:
162 return "%s(<NULL>)" % type(self).__name__
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000163_check_size(py_object, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000164
165class c_short(_SimpleCData):
166 _type_ = "h"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000167_check_size(c_short)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000168
169class c_ushort(_SimpleCData):
170 _type_ = "H"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000171_check_size(c_ushort)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000172
173class c_long(_SimpleCData):
174 _type_ = "l"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000175_check_size(c_long)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000176
177class c_ulong(_SimpleCData):
178 _type_ = "L"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000179_check_size(c_ulong)
Tim Peterse8d09e52006-03-09 01:15:05 +0000180
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000181if _calcsize("i") == _calcsize("l"):
182 # if int and long have the same size, make c_int an alias for c_long
183 c_int = c_long
184 c_uint = c_ulong
185else:
186 class c_int(_SimpleCData):
187 _type_ = "i"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000188 _check_size(c_int)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000189
190 class c_uint(_SimpleCData):
191 _type_ = "I"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000192 _check_size(c_uint)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000193
194class c_float(_SimpleCData):
195 _type_ = "f"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000196_check_size(c_float)
Tim Peterse8d09e52006-03-09 01:15:05 +0000197
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000198class c_double(_SimpleCData):
199 _type_ = "d"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000200_check_size(c_double)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000201
Thomas Wouters89d996e2007-09-08 17:39:28 +0000202class c_longdouble(_SimpleCData):
Thomas Hellerff721222008-01-17 18:46:55 +0000203 _type_ = "g"
Thomas Wouters89d996e2007-09-08 17:39:28 +0000204if sizeof(c_longdouble) == sizeof(c_double):
205 c_longdouble = c_double
206
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000207if _calcsize("l") == _calcsize("q"):
208 # if long and long long have the same size, make c_longlong an alias for c_long
209 c_longlong = c_long
210 c_ulonglong = c_ulong
211else:
212 class c_longlong(_SimpleCData):
213 _type_ = "q"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000214 _check_size(c_longlong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000215
216 class c_ulonglong(_SimpleCData):
217 _type_ = "Q"
218 ## def from_param(cls, val):
219 ## return ('d', float(val), val)
220 ## from_param = classmethod(from_param)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000221 _check_size(c_ulonglong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000222
223class c_ubyte(_SimpleCData):
224 _type_ = "B"
225c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
226# backward compatibility:
227##c_uchar = c_ubyte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000228_check_size(c_ubyte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000229
230class c_byte(_SimpleCData):
231 _type_ = "b"
232c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000233_check_size(c_byte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000234
235class c_char(_SimpleCData):
236 _type_ = "c"
237c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000238_check_size(c_char)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000239
240class c_char_p(_SimpleCData):
241 _type_ = "z"
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000242 if _os.name == "nt":
243 def __repr__(self):
244 if not windll.kernel32.IsBadStringPtrA(self, -1):
245 return "%s(%r)" % (self.__class__.__name__, self.value)
246 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
247 else:
248 def __repr__(self):
249 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000250_check_size(c_char_p, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000251
252class c_void_p(_SimpleCData):
253 _type_ = "P"
254c_voidp = c_void_p # backwards compatibility (to a bug)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000255_check_size(c_void_p)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000256
Guido van Rossumd8faa362007-04-27 19:54:29 +0000257class c_bool(_SimpleCData):
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000258 _type_ = "?"
Guido van Rossumd8faa362007-04-27 19:54:29 +0000259
Thomas Heller3071f812008-04-14 16:17:33 +0000260from _ctypes import POINTER, pointer, _pointer_type_cache
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000261
Victor Stinnercf448832010-07-28 00:15:03 +0000262class c_wchar_p(_SimpleCData):
263 _type_ = "Z"
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000264
Victor Stinnercf448832010-07-28 00:15:03 +0000265class c_wchar(_SimpleCData):
266 _type_ = "u"
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000267
Meador Inge11e38132011-11-25 22:33:32 -0600268def _reset_cache():
269 _pointer_type_cache.clear()
270 _c_functype_cache.clear()
271 if _os.name in ("nt", "ce"):
272 _win_functype_cache.clear()
273 # _SimpleCData.c_wchar_p_from_param
274 POINTER(c_wchar).from_param = c_wchar_p.from_param
275 # _SimpleCData.c_char_p_from_param
276 POINTER(c_char).from_param = c_char_p.from_param
277 _pointer_type_cache[None] = c_void_p
278 # XXX for whatever reasons, creating the first instance of a callback
279 # function is needed for the unittests on Win64 to succeed. This MAY
280 # be a compiler bug, since the problem occurs only when _ctypes is
281 # compiled with the MS SDK compiler. Or an uninitialized variable?
282 CFUNCTYPE(c_int)(lambda: None)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000283
Victor Stinnercf448832010-07-28 00:15:03 +0000284def create_unicode_buffer(init, size=None):
285 """create_unicode_buffer(aString) -> character array
286 create_unicode_buffer(anInteger) -> character array
287 create_unicode_buffer(aString, anInteger) -> character array
288 """
289 if isinstance(init, (str, bytes)):
290 if size is None:
291 size = len(init)+1
292 buftype = c_wchar * size
293 buf = buftype()
294 buf.value = init
295 return buf
296 elif isinstance(init, int):
297 buftype = c_wchar * init
298 buf = buftype()
299 return buf
300 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000301
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000302
303# XXX Deprecated
304def SetPointerType(pointer, cls):
305 if _pointer_type_cache.get(cls, None) is not None:
Collin Wintera73bfee2007-08-30 03:47:13 +0000306 raise RuntimeError("This type already exists in the cache")
Guido van Rossum1b01e5c2006-08-19 02:45:06 +0000307 if id(pointer) not in _pointer_type_cache:
Collin Wintera73bfee2007-08-30 03:47:13 +0000308 raise RuntimeError("What's this???")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000309 pointer.set_type(cls)
310 _pointer_type_cache[cls] = pointer
311 del _pointer_type_cache[id(pointer)]
312
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000313# XXX Deprecated
314def ARRAY(typ, len):
315 return typ * len
316
317################################################################
318
319
320class CDLL(object):
321 """An instance of this class represents a loaded dll/shared
322 library, exporting functions using the standard C calling
323 convention (named 'cdecl' on Windows).
324
325 The exported functions can be accessed as attributes, or by
326 indexing with the function name. Examples:
327
328 <obj>.qsort -> callable object
329 <obj>['qsort'] -> callable object
330
331 Calling the functions releases the Python GIL during the call and
Thomas Woutersed03b412007-08-28 21:37:11 +0000332 reacquires it afterwards.
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000333 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000334 _func_flags_ = _FUNCFLAG_CDECL
335 _func_restype_ = c_int
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000336
Thomas Heller9cac7b62008-06-06 09:31:40 +0000337 def __init__(self, name, mode=DEFAULT_MODE, handle=None,
338 use_errno=False,
339 use_last_error=False):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000340 self._name = name
Thomas Heller9cac7b62008-06-06 09:31:40 +0000341 flags = self._func_flags_
342 if use_errno:
343 flags |= _FUNCFLAG_USE_ERRNO
344 if use_last_error:
345 flags |= _FUNCFLAG_USE_LASTERROR
346
347 class _FuncPtr(_CFuncPtr):
348 _flags_ = flags
349 _restype_ = self._func_restype_
350 self._FuncPtr = _FuncPtr
351
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000352 if handle is None:
353 self._handle = _dlopen(self._name, mode)
354 else:
355 self._handle = handle
356
357 def __repr__(self):
358 return "<%s '%s', handle %x at %x>" % \
359 (self.__class__.__name__, self._name,
Christian Heimesa37d4c62007-12-04 23:02:19 +0000360 (self._handle & (_sys.maxsize*2 + 1)),
361 id(self) & (_sys.maxsize*2 + 1))
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000362
363 def __getattr__(self, name):
364 if name.startswith('__') and name.endswith('__'):
Collin Wintera73bfee2007-08-30 03:47:13 +0000365 raise AttributeError(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000366 func = self.__getitem__(name)
367 setattr(self, name, func)
368 return func
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000369
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000370 def __getitem__(self, name_or_ordinal):
371 func = self._FuncPtr((name_or_ordinal, self))
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000372 if not isinstance(name_or_ordinal, int):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000373 func.__name__ = name_or_ordinal
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000374 return func
375
376class PyDLL(CDLL):
377 """This class represents the Python library itself. It allows to
378 access Python API functions. The GIL is not released, and
379 Python exceptions are handled correctly.
380 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000381 _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000382
383if _os.name in ("nt", "ce"):
Tim Peterse8d09e52006-03-09 01:15:05 +0000384
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000385 class WinDLL(CDLL):
386 """This class represents a dll exporting functions using the
387 Windows stdcall calling convention.
388 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000389 _func_flags_ = _FUNCFLAG_STDCALL
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000390
391 # XXX Hm, what about HRESULT as normal parameter?
392 # Mustn't it derive from c_long then?
393 from _ctypes import _check_HRESULT, _SimpleCData
394 class HRESULT(_SimpleCData):
395 _type_ = "l"
396 # _check_retval_ is called with the function's result when it
397 # is used as restype. It checks for the FAILED bit, and
398 # raises a WindowsError if it is set.
399 #
400 # The _check_retval_ method is implemented in C, so that the
401 # method definition itself is not included in the traceback
402 # when it raises an error - that is what we want (and Python
403 # doesn't have a way to raise an exception in the caller's
404 # frame).
405 _check_retval_ = _check_HRESULT
Tim Peterse8d09e52006-03-09 01:15:05 +0000406
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000407 class OleDLL(CDLL):
408 """This class represents a dll exporting functions using the
409 Windows stdcall calling convention, and returning HRESULT.
410 HRESULT error values are automatically raised as WindowsError
411 exceptions.
412 """
Thomas Heller9cac7b62008-06-06 09:31:40 +0000413 _func_flags_ = _FUNCFLAG_STDCALL
414 _func_restype_ = HRESULT
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000415
Thomas Wouters477c8d52006-05-27 19:21:47 +0000416class LibraryLoader(object):
417 def __init__(self, dlltype):
418 self._dlltype = dlltype
419
420 def __getattr__(self, name):
421 if name[0] == '_':
422 raise AttributeError(name)
423 dll = self._dlltype(name)
424 setattr(self, name, dll)
425 return dll
426
427 def __getitem__(self, name):
428 return getattr(self, name)
429
430 def LoadLibrary(self, name):
431 return self._dlltype(name)
432
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000433cdll = LibraryLoader(CDLL)
434pydll = LibraryLoader(PyDLL)
435
436if _os.name in ("nt", "ce"):
437 pythonapi = PyDLL("python dll", None, _sys.dllhandle)
438elif _sys.platform == "cygwin":
439 pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
440else:
441 pythonapi = PyDLL(None)
442
443
444if _os.name in ("nt", "ce"):
445 windll = LibraryLoader(WinDLL)
446 oledll = LibraryLoader(OleDLL)
447
448 if _os.name == "nt":
449 GetLastError = windll.kernel32.GetLastError
450 else:
451 GetLastError = windll.coredll.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()
Richard Oudkerkea69bd32012-10-09 13:28:10 +0100459 return WindowsError(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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000512if _os.name in ("nt", "ce"): # 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()