blob: abda3dfcbef91e84010dd4c141a111e69f5e5ccb [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
Guido van Rossum8ce8a782007-11-01 19:42:39 +000029 if int(_os.uname()[2].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, \
33 FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI
34
Thomas Hellerbabddfc2006-03-08 19:56:54 +000035"""
36WINOLEAPI -> HRESULT
37WINOLEAPI_(type)
38
39STDMETHODCALLTYPE
40
41STDMETHOD(name)
42STDMETHOD_(type, name)
43
44STDAPICALLTYPE
45"""
46
47def create_string_buffer(init, size=None):
Guido van Rossum97f9d4f2007-10-24 18:41:19 +000048 """create_string_buffer(aBytes) -> character array
Thomas Hellerbabddfc2006-03-08 19:56:54 +000049 create_string_buffer(anInteger) -> character array
50 create_string_buffer(aString, anInteger) -> character array
51 """
Guido van Rossum97f9d4f2007-10-24 18:41:19 +000052 if isinstance(init, (str, bytes)):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000053 if size is None:
54 size = len(init)+1
55 buftype = c_char * size
56 buf = buftype()
57 buf.value = init
58 return buf
Walter Dörwaldaa97f042007-05-03 21:05:51 +000059 elif isinstance(init, int):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000060 buftype = c_char * init
61 buf = buftype()
62 return buf
Collin Wintera73bfee2007-08-30 03:47:13 +000063 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +000064
65def c_buffer(init, size=None):
66## "deprecated, use create_string_buffer instead"
67## import warnings
68## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
69## DeprecationWarning, stacklevel=2)
70 return create_string_buffer(init, size)
71
72_c_functype_cache = {}
73def CFUNCTYPE(restype, *argtypes):
74 """CFUNCTYPE(restype, *argtypes) -> function prototype.
Tim Peterse8d09e52006-03-09 01:15:05 +000075
Thomas Hellerbabddfc2006-03-08 19:56:54 +000076 restype: the result type
77 argtypes: a sequence specifying the argument types
Tim Peterse8d09e52006-03-09 01:15:05 +000078
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079 The function prototype can be called in different ways to create a
Thomas Hellerbabddfc2006-03-08 19:56:54 +000080 callable object:
Tim Peterse8d09e52006-03-09 01:15:05 +000081
Thomas Wouters477c8d52006-05-27 19:21:47 +000082 prototype(integer address) -> foreign function
83 prototype(callable) -> create and return a C callable function from callable
84 prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
85 prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
86 prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
Thomas Hellerbabddfc2006-03-08 19:56:54 +000087 """
88 try:
89 return _c_functype_cache[(restype, argtypes)]
90 except KeyError:
91 class CFunctionType(_CFuncPtr):
92 _argtypes_ = argtypes
93 _restype_ = restype
94 _flags_ = _FUNCFLAG_CDECL
95 _c_functype_cache[(restype, argtypes)] = CFunctionType
96 return CFunctionType
97
98if _os.name in ("nt", "ce"):
99 from _ctypes import LoadLibrary as _dlopen
100 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
101 if _os.name == "ce":
102 # 'ce' doesn't have the stdcall calling convention
103 _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
104
105 _win_functype_cache = {}
106 def WINFUNCTYPE(restype, *argtypes):
107 # docstring set later (very similar to CFUNCTYPE.__doc__)
108 try:
109 return _win_functype_cache[(restype, argtypes)]
110 except KeyError:
111 class WinFunctionType(_CFuncPtr):
112 _argtypes_ = argtypes
113 _restype_ = restype
114 _flags_ = _FUNCFLAG_STDCALL
115 _win_functype_cache[(restype, argtypes)] = WinFunctionType
116 return WinFunctionType
117 if WINFUNCTYPE.__doc__:
118 WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
119
120elif _os.name == "posix":
121 from _ctypes import dlopen as _dlopen
122
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000123from _ctypes import sizeof, byref, addressof, alignment, resize
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000124from _ctypes import _SimpleCData
125
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000126def _check_size(typ, typecode=None):
127 # Check if sizeof(ctypes_type) against struct.calcsize. This
128 # should protect somewhat against a misconfigured libffi.
129 from struct import calcsize
130 if typecode is None:
131 # Most _type_ codes are the same as used in struct
132 typecode = typ._type_
133 actual, required = sizeof(typ), calcsize(typecode)
134 if actual != required:
135 raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
136 (typ, actual, required))
137
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000138class py_object(_SimpleCData):
139 _type_ = "O"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000140 def __repr__(self):
141 try:
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000142 return super().__repr__()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000143 except ValueError:
144 return "%s(<NULL>)" % type(self).__name__
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000145_check_size(py_object, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000146
147class c_short(_SimpleCData):
148 _type_ = "h"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000149_check_size(c_short)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000150
151class c_ushort(_SimpleCData):
152 _type_ = "H"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000153_check_size(c_ushort)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000154
155class c_long(_SimpleCData):
156 _type_ = "l"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000157_check_size(c_long)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000158
159class c_ulong(_SimpleCData):
160 _type_ = "L"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000161_check_size(c_ulong)
Tim Peterse8d09e52006-03-09 01:15:05 +0000162
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000163if _calcsize("i") == _calcsize("l"):
164 # if int and long have the same size, make c_int an alias for c_long
165 c_int = c_long
166 c_uint = c_ulong
167else:
168 class c_int(_SimpleCData):
169 _type_ = "i"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000170 _check_size(c_int)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000171
172 class c_uint(_SimpleCData):
173 _type_ = "I"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000174 _check_size(c_uint)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000175
176class c_float(_SimpleCData):
177 _type_ = "f"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000178_check_size(c_float)
Tim Peterse8d09e52006-03-09 01:15:05 +0000179
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000180class c_double(_SimpleCData):
181 _type_ = "d"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000182_check_size(c_double)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000183
Thomas Wouters89d996e2007-09-08 17:39:28 +0000184class c_longdouble(_SimpleCData):
Thomas Hellerff721222008-01-17 18:46:55 +0000185 _type_ = "g"
Thomas Wouters89d996e2007-09-08 17:39:28 +0000186if sizeof(c_longdouble) == sizeof(c_double):
187 c_longdouble = c_double
188
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000189if _calcsize("l") == _calcsize("q"):
190 # if long and long long have the same size, make c_longlong an alias for c_long
191 c_longlong = c_long
192 c_ulonglong = c_ulong
193else:
194 class c_longlong(_SimpleCData):
195 _type_ = "q"
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000196 _check_size(c_longlong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000197
198 class c_ulonglong(_SimpleCData):
199 _type_ = "Q"
200 ## def from_param(cls, val):
201 ## return ('d', float(val), val)
202 ## from_param = classmethod(from_param)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000203 _check_size(c_ulonglong)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000204
205class c_ubyte(_SimpleCData):
206 _type_ = "B"
207c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
208# backward compatibility:
209##c_uchar = c_ubyte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000210_check_size(c_ubyte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000211
212class c_byte(_SimpleCData):
213 _type_ = "b"
214c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000215_check_size(c_byte)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000216
217class c_char(_SimpleCData):
218 _type_ = "c"
219c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000220_check_size(c_char)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000221
222class c_char_p(_SimpleCData):
223 _type_ = "z"
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000224 if _os.name == "nt":
225 def __repr__(self):
226 if not windll.kernel32.IsBadStringPtrA(self, -1):
227 return "%s(%r)" % (self.__class__.__name__, self.value)
228 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
229 else:
230 def __repr__(self):
231 return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000232_check_size(c_char_p, "P")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000233
234class c_void_p(_SimpleCData):
235 _type_ = "P"
236c_voidp = c_void_p # backwards compatibility (to a bug)
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000237_check_size(c_void_p)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000238
Guido van Rossumd8faa362007-04-27 19:54:29 +0000239class c_bool(_SimpleCData):
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000240 _type_ = "?"
Guido van Rossumd8faa362007-04-27 19:54:29 +0000241
Thomas Heller3071f812008-04-14 16:17:33 +0000242from _ctypes import POINTER, pointer, _pointer_type_cache
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000243
244try:
245 from _ctypes import set_conversion_mode
246except ImportError:
247 pass
248else:
249 if _os.name in ("nt", "ce"):
250 set_conversion_mode("mbcs", "ignore")
251 else:
252 set_conversion_mode("ascii", "strict")
253
254 class c_wchar_p(_SimpleCData):
255 _type_ = "Z"
256
257 class c_wchar(_SimpleCData):
258 _type_ = "u"
259
260 POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param
261
262 def create_unicode_buffer(init, size=None):
263 """create_unicode_buffer(aString) -> character array
264 create_unicode_buffer(anInteger) -> character array
265 create_unicode_buffer(aString, anInteger) -> character array
266 """
Thomas Heller60831312007-07-12 19:06:25 +0000267 if isinstance(init, (str, bytes)):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000268 if size is None:
269 size = len(init)+1
270 buftype = c_wchar * size
271 buf = buftype()
272 buf.value = init
273 return buf
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000274 elif isinstance(init, int):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000275 buftype = c_wchar * init
276 buf = buftype()
277 return buf
Collin Wintera73bfee2007-08-30 03:47:13 +0000278 raise TypeError(init)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000279
280POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param
281
282# XXX Deprecated
283def SetPointerType(pointer, cls):
284 if _pointer_type_cache.get(cls, None) is not None:
Collin Wintera73bfee2007-08-30 03:47:13 +0000285 raise RuntimeError("This type already exists in the cache")
Guido van Rossum1b01e5c2006-08-19 02:45:06 +0000286 if id(pointer) not in _pointer_type_cache:
Collin Wintera73bfee2007-08-30 03:47:13 +0000287 raise RuntimeError("What's this???")
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000288 pointer.set_type(cls)
289 _pointer_type_cache[cls] = pointer
290 del _pointer_type_cache[id(pointer)]
291
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000292# XXX Deprecated
293def ARRAY(typ, len):
294 return typ * len
295
296################################################################
297
298
299class CDLL(object):
300 """An instance of this class represents a loaded dll/shared
301 library, exporting functions using the standard C calling
302 convention (named 'cdecl' on Windows).
303
304 The exported functions can be accessed as attributes, or by
305 indexing with the function name. Examples:
306
307 <obj>.qsort -> callable object
308 <obj>['qsort'] -> callable object
309
310 Calling the functions releases the Python GIL during the call and
Thomas Woutersed03b412007-08-28 21:37:11 +0000311 reacquires it afterwards.
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000312 """
313 class _FuncPtr(_CFuncPtr):
314 _flags_ = _FUNCFLAG_CDECL
315 _restype_ = c_int # default, can be overridden in instances
316
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000317 def __init__(self, name, mode=DEFAULT_MODE, handle=None):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000318 self._name = name
319 if handle is None:
320 self._handle = _dlopen(self._name, mode)
321 else:
322 self._handle = handle
323
324 def __repr__(self):
325 return "<%s '%s', handle %x at %x>" % \
326 (self.__class__.__name__, self._name,
Christian Heimesa37d4c62007-12-04 23:02:19 +0000327 (self._handle & (_sys.maxsize*2 + 1)),
328 id(self) & (_sys.maxsize*2 + 1))
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000329
330 def __getattr__(self, name):
331 if name.startswith('__') and name.endswith('__'):
Collin Wintera73bfee2007-08-30 03:47:13 +0000332 raise AttributeError(name)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000333 func = self.__getitem__(name)
334 setattr(self, name, func)
335 return func
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000336
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000337 def __getitem__(self, name_or_ordinal):
338 func = self._FuncPtr((name_or_ordinal, self))
Walter Dörwaldaa97f042007-05-03 21:05:51 +0000339 if not isinstance(name_or_ordinal, int):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000340 func.__name__ = name_or_ordinal
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000341 return func
342
343class PyDLL(CDLL):
344 """This class represents the Python library itself. It allows to
345 access Python API functions. The GIL is not released, and
346 Python exceptions are handled correctly.
347 """
348 class _FuncPtr(_CFuncPtr):
349 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
350 _restype_ = c_int # default, can be overridden in instances
351
352if _os.name in ("nt", "ce"):
Tim Peterse8d09e52006-03-09 01:15:05 +0000353
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000354 class WinDLL(CDLL):
355 """This class represents a dll exporting functions using the
356 Windows stdcall calling convention.
357 """
358 class _FuncPtr(_CFuncPtr):
359 _flags_ = _FUNCFLAG_STDCALL
360 _restype_ = c_int # default, can be overridden in instances
361
362 # XXX Hm, what about HRESULT as normal parameter?
363 # Mustn't it derive from c_long then?
364 from _ctypes import _check_HRESULT, _SimpleCData
365 class HRESULT(_SimpleCData):
366 _type_ = "l"
367 # _check_retval_ is called with the function's result when it
368 # is used as restype. It checks for the FAILED bit, and
369 # raises a WindowsError if it is set.
370 #
371 # The _check_retval_ method is implemented in C, so that the
372 # method definition itself is not included in the traceback
373 # when it raises an error - that is what we want (and Python
374 # doesn't have a way to raise an exception in the caller's
375 # frame).
376 _check_retval_ = _check_HRESULT
Tim Peterse8d09e52006-03-09 01:15:05 +0000377
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000378 class OleDLL(CDLL):
379 """This class represents a dll exporting functions using the
380 Windows stdcall calling convention, and returning HRESULT.
381 HRESULT error values are automatically raised as WindowsError
382 exceptions.
383 """
384 class _FuncPtr(_CFuncPtr):
385 _flags_ = _FUNCFLAG_STDCALL
386 _restype_ = HRESULT
387
Thomas Wouters477c8d52006-05-27 19:21:47 +0000388class LibraryLoader(object):
389 def __init__(self, dlltype):
390 self._dlltype = dlltype
391
392 def __getattr__(self, name):
393 if name[0] == '_':
394 raise AttributeError(name)
395 dll = self._dlltype(name)
396 setattr(self, name, dll)
397 return dll
398
399 def __getitem__(self, name):
400 return getattr(self, name)
401
402 def LoadLibrary(self, name):
403 return self._dlltype(name)
404
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000405cdll = LibraryLoader(CDLL)
406pydll = LibraryLoader(PyDLL)
407
408if _os.name in ("nt", "ce"):
409 pythonapi = PyDLL("python dll", None, _sys.dllhandle)
410elif _sys.platform == "cygwin":
411 pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
412else:
413 pythonapi = PyDLL(None)
414
415
416if _os.name in ("nt", "ce"):
417 windll = LibraryLoader(WinDLL)
418 oledll = LibraryLoader(OleDLL)
419
420 if _os.name == "nt":
421 GetLastError = windll.kernel32.GetLastError
422 else:
423 GetLastError = windll.coredll.GetLastError
424
425 def WinError(code=None, descr=None):
426 if code is None:
427 code = GetLastError()
428 if descr is None:
429 descr = FormatError(code).strip()
430 return WindowsError(code, descr)
431
432_pointer_type_cache[None] = c_void_p
433
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000434if sizeof(c_uint) == sizeof(c_void_p):
435 c_size_t = c_uint
436elif sizeof(c_ulong) == sizeof(c_void_p):
437 c_size_t = c_ulong
Thomas Wouters89f507f2006-12-13 04:49:30 +0000438elif sizeof(c_ulonglong) == sizeof(c_void_p):
439 c_size_t = c_ulonglong
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000440
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000441# functions
442
443from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
444
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000445## void *memmove(void *, const void *, size_t);
446memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
447
448## void *memset(void *, int, size_t)
449memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
450
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000451def PYFUNCTYPE(restype, *argtypes):
452 class CFunctionType(_CFuncPtr):
453 _argtypes_ = argtypes
454 _restype_ = restype
455 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
456 return CFunctionType
Thomas Wouters477c8d52006-05-27 19:21:47 +0000457
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000458_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000459def cast(obj, typ):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000460 return _cast(obj, obj, typ)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000461
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000462_string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000463def string_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000464 """string_at(addr[, size]) -> string
465
466 Return the string at addr."""
467 return _string_at(ptr, size)
468
469try:
470 from _ctypes import _wstring_at_addr
471except ImportError:
472 pass
473else:
474 _wstring_at = CFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000475 def wstring_at(ptr, size=-1):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000476 """wstring_at(addr[, size]) -> string
477
478 Return the string at addr."""
479 return _wstring_at(ptr, size)
Tim Peterse8d09e52006-03-09 01:15:05 +0000480
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000481
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000482if _os.name in ("nt", "ce"): # COM stuff
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000483 def DllGetClassObject(rclsid, riid, ppv):
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000484 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000485 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000486 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000487 return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000488 else:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000489 return ccom.DllGetClassObject(rclsid, riid, ppv)
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000490
491 def DllCanUnloadNow():
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000492 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000493 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000494 except ImportError:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000495 return 0 # S_OK
496 return ccom.DllCanUnloadNow()
Thomas Hellerbabddfc2006-03-08 19:56:54 +0000497
498from ctypes._endian import BigEndianStructure, LittleEndianStructure
499
500# Fill in specifically-sized types
501c_int8 = c_byte
502c_uint8 = c_ubyte
503for kind in [c_short, c_int, c_long, c_longlong]:
504 if sizeof(kind) == 2: c_int16 = kind
505 elif sizeof(kind) == 4: c_int32 = kind
506 elif sizeof(kind) == 8: c_int64 = kind
507for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
508 if sizeof(kind) == 2: c_uint16 = kind
509 elif sizeof(kind) == 4: c_uint32 = kind
510 elif sizeof(kind) == 8: c_uint64 = kind
511del(kind)
Thomas Heller674e9382007-08-31 13:06:44 +0000512
513# XXX for whatever reasons, creating the first instance of a callback
514# function is needed for the unittests on Win64 to succeed. This MAY
515# be a compiler bug, since the problem occurs only when _ctypes is
516# compiled with the MS SDK compiler. Or an uninitialized variable?
517CFUNCTYPE(c_int)(lambda: None)