blob: cc05e97c8a80f0564add037e2922688b3e7688ca [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":
24 import gestalt
25
26 # gestalt.gestalt("sysv") returns the version number of the
27 # currently active system file as BCD.
28 # On OS X 10.4.6 -> 0x1046
29 # On OS X 10.2.8 -> 0x1028
30 # See also http://www.rgaros.nl/gestalt/
31 #
32 # On OS X 10.3, we use RTLD_GLOBAL as default mode
33 # because RTLD_LOCAL does not work at least on some
34 # libraries.
35
36 if gestalt.gestalt("sysv") < 0x1040:
37 DEFAULT_MODE = RTLD_GLOBAL
38
Thomas Hellerbabddfc2006-03-08 19:56:54 +000039from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
40 FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI
41
Thomas Hellerbabddfc2006-03-08 19:56:54 +000042"""
43WINOLEAPI -> HRESULT
44WINOLEAPI_(type)
45
46STDMETHODCALLTYPE
47
48STDMETHOD(name)
49STDMETHOD_(type, name)
50
51STDAPICALLTYPE
52"""
53
54def create_string_buffer(init, size=None):
Guido van Rossum97f9d4f2007-10-24 18:41:19 +000055 """create_string_buffer(aBytes) -> character array
Thomas Hellerbabddfc2006-03-08 19:56:54 +000056 create_string_buffer(anInteger) -> character array
57 create_string_buffer(aString, anInteger) -> character array
58 """
Guido van Rossum97f9d4f2007-10-24 18:41:19 +000059 if isinstance(init, (str, bytes)):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000060 if size is None:
61 size = len(init)+1
62 buftype = c_char * size
63 buf = buftype()
64 buf.value = init
65 return buf
Walter Dörwaldaa97f042007-05-03 21:05:51 +000066 elif isinstance(init, int):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000067 buftype = c_char * init
68 buf = buftype()
69 return buf
Collin Wintera73bfee2007-08-30 03:47:13 +000070 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +000071
72def c_buffer(init, size=None):
73## "deprecated, use create_string_buffer instead"
74## import warnings
75## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
76## DeprecationWarning, stacklevel=2)
77 return create_string_buffer(init, size)
78
79_c_functype_cache = {}
80def CFUNCTYPE(restype, *argtypes):
81 """CFUNCTYPE(restype, *argtypes) -> function prototype.
Tim Peterse8d09e52006-03-09 01:15:05 +000082
Thomas Hellerbabddfc2006-03-08 19:56:54 +000083 restype: the result type
84 argtypes: a sequence specifying the argument types
Tim Peterse8d09e52006-03-09 01:15:05 +000085
Thomas Wouters0e3f5912006-08-11 14:57:12 +000086 The function prototype can be called in different ways to create a
Thomas Hellerbabddfc2006-03-08 19:56:54 +000087 callable object:
Tim Peterse8d09e52006-03-09 01:15:05 +000088
Thomas Wouters477c8d52006-05-27 19:21:47 +000089 prototype(integer address) -> foreign function
90 prototype(callable) -> create and return a C callable function from callable
91 prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
92 prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
93 prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
Thomas Hellerbabddfc2006-03-08 19:56:54 +000094 """
95 try:
96 return _c_functype_cache[(restype, argtypes)]
97 except KeyError:
98 class CFunctionType(_CFuncPtr):
99 _argtypes_ = argtypes
100 _restype_ = restype
101 _flags_ = _FUNCFLAG_CDECL
102 _c_functype_cache[(restype, argtypes)] = CFunctionType
103 return CFunctionType
104
105if _os.name in ("nt", "ce"):
106 from _ctypes import LoadLibrary as _dlopen
107 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
108 if _os.name == "ce":
109 # 'ce' doesn't have the stdcall calling convention
110 _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
111
112 _win_functype_cache = {}
113 def WINFUNCTYPE(restype, *argtypes):
114 # docstring set later (very similar to CFUNCTYPE.__doc__)
115 try:
116 return _win_functype_cache[(restype, argtypes)]
117 except KeyError:
118 class WinFunctionType(_CFuncPtr):
119 _argtypes_ = argtypes
120 _restype_ = restype
121 _flags_ = _FUNCFLAG_STDCALL
122 _win_functype_cache[(restype, argtypes)] = WinFunctionType
123 return WinFunctionType
124 if WINFUNCTYPE.__doc__:
125 WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
126
127elif _os.name == "posix":
128 from _ctypes import dlopen as _dlopen
129
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000130from _ctypes import sizeof, byref, addressof, alignment, resize
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000131from _ctypes import _SimpleCData
132
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000133def _check_size(typ, typecode=None):
134 # Check if sizeof(ctypes_type) against struct.calcsize. This
135 # should protect somewhat against a misconfigured libffi.
136 from struct import calcsize
137 if typecode is None:
138 # Most _type_ codes are the same as used in struct
139 typecode = typ._type_
140 actual, required = sizeof(typ), calcsize(typecode)
141 if actual != required:
142 raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
143 (typ, actual, required))
144
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000145class py_object(_SimpleCData):
146 _type_ = "O"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000147 def __repr__(self):
148 try:
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000149 return super().__repr__()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000150 except ValueError:
151 return "%s(<NULL>)" % type(self).__name__
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000152_check_size(py_object, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000153
154class c_short(_SimpleCData):
155 _type_ = "h"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000156_check_size(c_short)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000157
158class c_ushort(_SimpleCData):
159 _type_ = "H"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000160_check_size(c_ushort)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000161
162class c_long(_SimpleCData):
163 _type_ = "l"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000164_check_size(c_long)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000165
166class c_ulong(_SimpleCData):
167 _type_ = "L"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000168_check_size(c_ulong)
Tim Peterse8d09e52006-03-09 01:15:05 +0000169
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000170if _calcsize("i") == _calcsize("l"):
171 # if int and long have the same size, make c_int an alias for c_long
172 c_int = c_long
173 c_uint = c_ulong
174else:
175 class c_int(_SimpleCData):
176 _type_ = "i"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000177 _check_size(c_int)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000178
179 class c_uint(_SimpleCData):
180 _type_ = "I"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000181 _check_size(c_uint)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000182
183class c_float(_SimpleCData):
184 _type_ = "f"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000185_check_size(c_float)
Tim Peterse8d09e52006-03-09 01:15:05 +0000186
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000187class c_double(_SimpleCData):
188 _type_ = "d"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000189_check_size(c_double)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000190
Thomas Wouters89d996e2007-09-08 17:39:28 +0000191class c_longdouble(_SimpleCData):
192 _type_ = "D"
193if sizeof(c_longdouble) == sizeof(c_double):
194 c_longdouble = c_double
195
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000196if _calcsize("l") == _calcsize("q"):
197 # if long and long long have the same size, make c_longlong an alias for c_long
198 c_longlong = c_long
199 c_ulonglong = c_ulong
200else:
201 class c_longlong(_SimpleCData):
202 _type_ = "q"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000203 _check_size(c_longlong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000204
205 class c_ulonglong(_SimpleCData):
206 _type_ = "Q"
207 ## def from_param(cls, val):
208 ## return ('d', float(val), val)
209 ## from_param = classmethod(from_param)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000210 _check_size(c_ulonglong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000211
212class c_ubyte(_SimpleCData):
213 _type_ = "B"
214c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
215# backward compatibility:
216##c_uchar = c_ubyte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000217_check_size(c_ubyte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000218
219class c_byte(_SimpleCData):
220 _type_ = "b"
221c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000222_check_size(c_byte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000223
224class c_char(_SimpleCData):
225 _type_ = "c"
226c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000227_check_size(c_char)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000228
229class c_char_p(_SimpleCData):
230 _type_ = "z"
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000231 if _os.name == "nt":
232 def __repr__(self):
233 if not windll.kernel32.IsBadStringPtrA(self, -1):
234 return "%s(%r)" % (self.__class__.__name__, self.value)
235 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
236 else:
237 def __repr__(self):
238 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).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):
247 _type_ = "t"
248
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000249# This cache maps types to pointers to them.
250_pointer_type_cache = {}
251
252def POINTER(cls):
253 try:
254 return _pointer_type_cache[cls]
255 except KeyError:
256 pass
257 if type(cls) is str:
258 klass = type(_Pointer)("LP_%s" % cls,
259 (_Pointer,),
260 {})
261 _pointer_type_cache[id(klass)] = klass
262 return klass
263 else:
264 name = "LP_%s" % cls.__name__
265 klass = type(_Pointer)(name,
266 (_Pointer,),
267 {'_type_': cls})
268 _pointer_type_cache[cls] = klass
269 return klass
270
271try:
272 from _ctypes import set_conversion_mode
273except ImportError:
274 pass
275else:
276 if _os.name in ("nt", "ce"):
277 set_conversion_mode("mbcs", "ignore")
278 else:
279 set_conversion_mode("ascii", "strict")
280
281 class c_wchar_p(_SimpleCData):
282 _type_ = "Z"
283
284 class c_wchar(_SimpleCData):
285 _type_ = "u"
286
287 POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param
288
289 def create_unicode_buffer(init, size=None):
290 """create_unicode_buffer(aString) -> character array
291 create_unicode_buffer(anInteger) -> character array
292 create_unicode_buffer(aString, anInteger) -> character array
293 """
Thomas Heller60831312007-07-12 19:06:25 +0000294 if isinstance(init, (str, bytes)):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000295 if size is None:
296 size = len(init)+1
297 buftype = c_wchar * size
298 buf = buftype()
299 buf.value = init
300 return buf
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000301 elif isinstance(init, int):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000302 buftype = c_wchar * init
303 buf = buftype()
304 return buf
Collin Wintera73bfee2007-08-30 03:47:13 +0000305 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000306
307POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param
308
309# XXX Deprecated
310def SetPointerType(pointer, cls):
311 if _pointer_type_cache.get(cls, None) is not None:
Collin Wintera73bfee2007-08-30 03:47:13 +0000312 raise RuntimeError("This type already exists in the cache")
Guido van Rossum1b01e5c2006-08-19 02:45:06 +0000313 if id(pointer) not in _pointer_type_cache:
Collin Wintera73bfee2007-08-30 03:47:13 +0000314 raise RuntimeError("What's this???")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000315 pointer.set_type(cls)
316 _pointer_type_cache[cls] = pointer
317 del _pointer_type_cache[id(pointer)]
318
319
320def pointer(inst):
321 return POINTER(type(inst))(inst)
322
323# XXX Deprecated
324def ARRAY(typ, len):
325 return typ * len
326
327################################################################
328
329
330class CDLL(object):
331 """An instance of this class represents a loaded dll/shared
332 library, exporting functions using the standard C calling
333 convention (named 'cdecl' on Windows).
334
335 The exported functions can be accessed as attributes, or by
336 indexing with the function name. Examples:
337
338 <obj>.qsort -> callable object
339 <obj>['qsort'] -> callable object
340
341 Calling the functions releases the Python GIL during the call and
Thomas Woutersed03b412007-08-28 21:37:11 +0000342 reacquires it afterwards.
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000343 """
344 class _FuncPtr(_CFuncPtr):
345 _flags_ = _FUNCFLAG_CDECL
346 _restype_ = c_int # default, can be overridden in instances
347
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000348 def __init__(self, name, mode=DEFAULT_MODE, handle=None):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000349 self._name = name
350 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,
358 (self._handle & (_sys.maxint*2 + 1)),
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000359 id(self) & (_sys.maxint*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 """
379 class _FuncPtr(_CFuncPtr):
380 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
381 _restype_ = c_int # default, can be overridden in instances
382
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 """
389 class _FuncPtr(_CFuncPtr):
390 _flags_ = _FUNCFLAG_STDCALL
391 _restype_ = c_int # default, can be overridden in instances
392
393 # XXX Hm, what about HRESULT as normal parameter?
394 # Mustn't it derive from c_long then?
395 from _ctypes import _check_HRESULT, _SimpleCData
396 class HRESULT(_SimpleCData):
397 _type_ = "l"
398 # _check_retval_ is called with the function's result when it
399 # is used as restype. It checks for the FAILED bit, and
400 # raises a WindowsError if it is set.
401 #
402 # The _check_retval_ method is implemented in C, so that the
403 # method definition itself is not included in the traceback
404 # when it raises an error - that is what we want (and Python
405 # doesn't have a way to raise an exception in the caller's
406 # frame).
407 _check_retval_ = _check_HRESULT
Tim Peterse8d09e52006-03-09 01:15:05 +0000408
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000409 class OleDLL(CDLL):
410 """This class represents a dll exporting functions using the
411 Windows stdcall calling convention, and returning HRESULT.
412 HRESULT error values are automatically raised as WindowsError
413 exceptions.
414 """
415 class _FuncPtr(_CFuncPtr):
416 _flags_ = _FUNCFLAG_STDCALL
417 _restype_ = HRESULT
418
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
439if _os.name in ("nt", "ce"):
440 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
447if _os.name in ("nt", "ce"):
448 windll = LibraryLoader(WinDLL)
449 oledll = LibraryLoader(OleDLL)
450
451 if _os.name == "nt":
452 GetLastError = windll.kernel32.GetLastError
453 else:
454 GetLastError = windll.coredll.GetLastError
455
456 def WinError(code=None, descr=None):
457 if code is None:
458 code = GetLastError()
459 if descr is None:
460 descr = FormatError(code).strip()
461 return WindowsError(code, descr)
462
463_pointer_type_cache[None] = c_void_p
464
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000465if sizeof(c_uint) == sizeof(c_void_p):
466 c_size_t = c_uint
467elif sizeof(c_ulong) == sizeof(c_void_p):
468 c_size_t = c_ulong
Thomas Wouters89f507f2006-12-13 04:49:30 +0000469elif sizeof(c_ulonglong) == sizeof(c_void_p):
470 c_size_t = c_ulonglong
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000471
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000472# functions
473
474from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
475
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000476## void *memmove(void *, const void *, size_t);
477memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
478
479## void *memset(void *, int, size_t)
480memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
481
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000482def PYFUNCTYPE(restype, *argtypes):
483 class CFunctionType(_CFuncPtr):
484 _argtypes_ = argtypes
485 _restype_ = restype
486 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
487 return CFunctionType
Thomas Wouters477c8d52006-05-27 19:21:47 +0000488
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000489_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000490def cast(obj, typ):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000491 return _cast(obj, obj, typ)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000492
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000493_string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000494def string_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000495 """string_at(addr[, size]) -> string
496
497 Return the string at addr."""
498 return _string_at(ptr, size)
499
500try:
501 from _ctypes import _wstring_at_addr
502except ImportError:
503 pass
504else:
505 _wstring_at = CFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000506 def wstring_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000507 """wstring_at(addr[, size]) -> string
508
509 Return the string at addr."""
510 return _wstring_at(ptr, size)
Tim Peterse8d09e52006-03-09 01:15:05 +0000511
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000512
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000513if _os.name in ("nt", "ce"): # COM stuff
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000514 def DllGetClassObject(rclsid, riid, ppv):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000515 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000516 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000517 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000518 return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000519 else:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000520 return ccom.DllGetClassObject(rclsid, riid, ppv)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000521
522 def DllCanUnloadNow():
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000523 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000524 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000525 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000526 return 0 # S_OK
527 return ccom.DllCanUnloadNow()
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000528
529from ctypes._endian import BigEndianStructure, LittleEndianStructure
530
531# Fill in specifically-sized types
532c_int8 = c_byte
533c_uint8 = c_ubyte
534for kind in [c_short, c_int, c_long, c_longlong]:
535 if sizeof(kind) == 2: c_int16 = kind
536 elif sizeof(kind) == 4: c_int32 = kind
537 elif sizeof(kind) == 8: c_int64 = kind
538for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
539 if sizeof(kind) == 2: c_uint16 = kind
540 elif sizeof(kind) == 4: c_uint32 = kind
541 elif sizeof(kind) == 8: c_uint64 = kind
542del(kind)
Thomas Heller674e9382007-08-31 13:06:44 +0000543
544# XXX for whatever reasons, creating the first instance of a callback
545# function is needed for the unittests on Win64 to succeed. This MAY
546# be a compiler bug, since the problem occurs only when _ctypes is
547# compiled with the MS SDK compiler. Or an uninitialized variable?
548CFUNCTYPE(c_int)(lambda: None)