Catch situations where currentframe() returns None. See SF patch #1447410, this is...
[python.git] / Lib / ctypes / __init__.py
blobdd0f640d9f22fcb5250302490e6c578e3831cb43
1 """create and manipulate C data types in Python"""
3 import os as _os, sys as _sys
4 from itertools import chain as _chain
6 __version__ = "0.9.9.4"
8 from _ctypes import Union, Structure, Array
9 from _ctypes import _Pointer
10 from _ctypes import CFuncPtr as _CFuncPtr
11 from _ctypes import __version__ as _ctypes_version
12 try:
13 from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
14 except (ImportError, AttributeError):
15 RTLD_GLOBAL = RTLD_LOCAL = None
17 from _ctypes import ArgumentError
19 from struct import calcsize as _calcsize
21 if __version__ != _ctypes_version:
22 raise Exception, ("Version number mismatch", __version__, _ctypes_version)
24 if _os.name in ("nt", "ce"):
25 from _ctypes import FormatError
27 from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
28 FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI
30 from ctypes._loader import LibraryLoader
32 """
33 WINOLEAPI -> HRESULT
34 WINOLEAPI_(type)
36 STDMETHODCALLTYPE
38 STDMETHOD(name)
39 STDMETHOD_(type, name)
41 STDAPICALLTYPE
42 """
44 def create_string_buffer(init, size=None):
45 """create_string_buffer(aString) -> character array
46 create_string_buffer(anInteger) -> character array
47 create_string_buffer(aString, anInteger) -> character array
48 """
49 if isinstance(init, (str, unicode)):
50 if size is None:
51 size = len(init)+1
52 buftype = c_char * size
53 buf = buftype()
54 buf.value = init
55 return buf
56 elif isinstance(init, (int, long)):
57 buftype = c_char * init
58 buf = buftype()
59 return buf
60 raise TypeError, init
62 def c_buffer(init, size=None):
63 ## "deprecated, use create_string_buffer instead"
64 ## import warnings
65 ## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
66 ## DeprecationWarning, stacklevel=2)
67 return create_string_buffer(init, size)
69 _c_functype_cache = {}
70 def CFUNCTYPE(restype, *argtypes):
71 """CFUNCTYPE(restype, *argtypes) -> function prototype.
73 restype: the result type
74 argtypes: a sequence specifying the argument types
76 The function prototype can be called in three ways to create a
77 callable object:
79 prototype(funct) - returns a C callable function calling funct
80 prototype(vtbl_index, method_name[, paramflags]) - a Python callable that calls a COM method
81 prototype(funct_name, dll[, paramflags]) - a Python callable that calls an exported function in a dll
82 """
83 try:
84 return _c_functype_cache[(restype, argtypes)]
85 except KeyError:
86 class CFunctionType(_CFuncPtr):
87 _argtypes_ = argtypes
88 _restype_ = restype
89 _flags_ = _FUNCFLAG_CDECL
90 _c_functype_cache[(restype, argtypes)] = CFunctionType
91 return CFunctionType
93 if _os.name in ("nt", "ce"):
94 from _ctypes import LoadLibrary as _dlopen
95 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
96 if _os.name == "ce":
97 # 'ce' doesn't have the stdcall calling convention
98 _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
100 _win_functype_cache = {}
101 def WINFUNCTYPE(restype, *argtypes):
102 # docstring set later (very similar to CFUNCTYPE.__doc__)
103 try:
104 return _win_functype_cache[(restype, argtypes)]
105 except KeyError:
106 class WinFunctionType(_CFuncPtr):
107 _argtypes_ = argtypes
108 _restype_ = restype
109 _flags_ = _FUNCFLAG_STDCALL
110 _win_functype_cache[(restype, argtypes)] = WinFunctionType
111 return WinFunctionType
112 if WINFUNCTYPE.__doc__:
113 WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
115 elif _os.name == "posix":
116 from _ctypes import dlopen as _dlopen
118 from _ctypes import sizeof, byref, addressof, alignment
119 from _ctypes import _SimpleCData
121 class py_object(_SimpleCData):
122 _type_ = "O"
124 class c_short(_SimpleCData):
125 _type_ = "h"
127 class c_ushort(_SimpleCData):
128 _type_ = "H"
130 class c_long(_SimpleCData):
131 _type_ = "l"
133 class c_ulong(_SimpleCData):
134 _type_ = "L"
136 if _calcsize("i") == _calcsize("l"):
137 # if int and long have the same size, make c_int an alias for c_long
138 c_int = c_long
139 c_uint = c_ulong
140 else:
141 class c_int(_SimpleCData):
142 _type_ = "i"
144 class c_uint(_SimpleCData):
145 _type_ = "I"
147 class c_float(_SimpleCData):
148 _type_ = "f"
150 class c_double(_SimpleCData):
151 _type_ = "d"
153 if _calcsize("l") == _calcsize("q"):
154 # if long and long long have the same size, make c_longlong an alias for c_long
155 c_longlong = c_long
156 c_ulonglong = c_ulong
157 else:
158 class c_longlong(_SimpleCData):
159 _type_ = "q"
161 class c_ulonglong(_SimpleCData):
162 _type_ = "Q"
163 ## def from_param(cls, val):
164 ## return ('d', float(val), val)
165 ## from_param = classmethod(from_param)
167 class c_ubyte(_SimpleCData):
168 _type_ = "B"
169 c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
170 # backward compatibility:
171 ##c_uchar = c_ubyte
173 class c_byte(_SimpleCData):
174 _type_ = "b"
175 c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
177 class c_char(_SimpleCData):
178 _type_ = "c"
179 c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
181 class c_char_p(_SimpleCData):
182 _type_ = "z"
184 class c_void_p(_SimpleCData):
185 _type_ = "P"
186 c_voidp = c_void_p # backwards compatibility (to a bug)
188 # This cache maps types to pointers to them.
189 _pointer_type_cache = {}
191 def POINTER(cls):
192 try:
193 return _pointer_type_cache[cls]
194 except KeyError:
195 pass
196 if type(cls) is str:
197 klass = type(_Pointer)("LP_%s" % cls,
198 (_Pointer,),
200 _pointer_type_cache[id(klass)] = klass
201 return klass
202 else:
203 name = "LP_%s" % cls.__name__
204 klass = type(_Pointer)(name,
205 (_Pointer,),
206 {'_type_': cls})
207 _pointer_type_cache[cls] = klass
208 return klass
210 try:
211 from _ctypes import set_conversion_mode
212 except ImportError:
213 pass
214 else:
215 if _os.name in ("nt", "ce"):
216 set_conversion_mode("mbcs", "ignore")
217 else:
218 set_conversion_mode("ascii", "strict")
220 class c_wchar_p(_SimpleCData):
221 _type_ = "Z"
223 class c_wchar(_SimpleCData):
224 _type_ = "u"
226 POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param
228 def create_unicode_buffer(init, size=None):
229 """create_unicode_buffer(aString) -> character array
230 create_unicode_buffer(anInteger) -> character array
231 create_unicode_buffer(aString, anInteger) -> character array
233 if isinstance(init, (str, unicode)):
234 if size is None:
235 size = len(init)+1
236 buftype = c_wchar * size
237 buf = buftype()
238 buf.value = init
239 return buf
240 elif isinstance(init, (int, long)):
241 buftype = c_wchar * init
242 buf = buftype()
243 return buf
244 raise TypeError, init
246 POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param
248 # XXX Deprecated
249 def SetPointerType(pointer, cls):
250 if _pointer_type_cache.get(cls, None) is not None:
251 raise RuntimeError, \
252 "This type already exists in the cache"
253 if not _pointer_type_cache.has_key(id(pointer)):
254 raise RuntimeError, \
255 "What's this???"
256 pointer.set_type(cls)
257 _pointer_type_cache[cls] = pointer
258 del _pointer_type_cache[id(pointer)]
261 def pointer(inst):
262 return POINTER(type(inst))(inst)
264 # XXX Deprecated
265 def ARRAY(typ, len):
266 return typ * len
268 ################################################################
271 class CDLL(object):
272 """An instance of this class represents a loaded dll/shared
273 library, exporting functions using the standard C calling
274 convention (named 'cdecl' on Windows).
276 The exported functions can be accessed as attributes, or by
277 indexing with the function name. Examples:
279 <obj>.qsort -> callable object
280 <obj>['qsort'] -> callable object
282 Calling the functions releases the Python GIL during the call and
283 reaquires it afterwards.
285 class _FuncPtr(_CFuncPtr):
286 _flags_ = _FUNCFLAG_CDECL
287 _restype_ = c_int # default, can be overridden in instances
289 def __init__(self, name, mode=RTLD_LOCAL, handle=None):
290 self._name = name
291 if handle is None:
292 self._handle = _dlopen(self._name, mode)
293 else:
294 self._handle = handle
296 def __repr__(self):
297 return "<%s '%s', handle %x at %x>" % \
298 (self.__class__.__name__, self._name,
299 (self._handle & (_sys.maxint*2 + 1)),
300 id(self))
302 def __getattr__(self, name):
303 if name.startswith('__') and name.endswith('__'):
304 raise AttributeError, name
305 return self.__getitem__(name)
307 def __getitem__(self, name):
308 func = self._FuncPtr(name, self)
309 func.__name__ = name
310 setattr(self, name, func)
311 return func
313 class PyDLL(CDLL):
314 """This class represents the Python library itself. It allows to
315 access Python API functions. The GIL is not released, and
316 Python exceptions are handled correctly.
318 class _FuncPtr(_CFuncPtr):
319 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
320 _restype_ = c_int # default, can be overridden in instances
322 if _os.name in ("nt", "ce"):
324 class WinDLL(CDLL):
325 """This class represents a dll exporting functions using the
326 Windows stdcall calling convention.
328 class _FuncPtr(_CFuncPtr):
329 _flags_ = _FUNCFLAG_STDCALL
330 _restype_ = c_int # default, can be overridden in instances
332 # XXX Hm, what about HRESULT as normal parameter?
333 # Mustn't it derive from c_long then?
334 from _ctypes import _check_HRESULT, _SimpleCData
335 class HRESULT(_SimpleCData):
336 _type_ = "l"
337 # _check_retval_ is called with the function's result when it
338 # is used as restype. It checks for the FAILED bit, and
339 # raises a WindowsError if it is set.
341 # The _check_retval_ method is implemented in C, so that the
342 # method definition itself is not included in the traceback
343 # when it raises an error - that is what we want (and Python
344 # doesn't have a way to raise an exception in the caller's
345 # frame).
346 _check_retval_ = _check_HRESULT
348 class OleDLL(CDLL):
349 """This class represents a dll exporting functions using the
350 Windows stdcall calling convention, and returning HRESULT.
351 HRESULT error values are automatically raised as WindowsError
352 exceptions.
354 class _FuncPtr(_CFuncPtr):
355 _flags_ = _FUNCFLAG_STDCALL
356 _restype_ = HRESULT
358 cdll = LibraryLoader(CDLL)
359 pydll = LibraryLoader(PyDLL)
361 if _os.name in ("nt", "ce"):
362 pythonapi = PyDLL("python dll", None, _sys.dllhandle)
363 elif _sys.platform == "cygwin":
364 pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
365 else:
366 pythonapi = PyDLL(None)
369 if _os.name in ("nt", "ce"):
370 windll = LibraryLoader(WinDLL)
371 oledll = LibraryLoader(OleDLL)
373 if _os.name == "nt":
374 GetLastError = windll.kernel32.GetLastError
375 else:
376 GetLastError = windll.coredll.GetLastError
378 def WinError(code=None, descr=None):
379 if code is None:
380 code = GetLastError()
381 if descr is None:
382 descr = FormatError(code).strip()
383 return WindowsError(code, descr)
385 _pointer_type_cache[None] = c_void_p
387 # functions
389 from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, cast
391 if sizeof(c_uint) == sizeof(c_void_p):
392 c_size_t = c_uint
393 elif sizeof(c_ulong) == sizeof(c_void_p):
394 c_size_t = c_ulong
396 ## void *memmove(void *, const void *, size_t);
397 memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
399 ## void *memset(void *, int, size_t)
400 memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
402 _string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
403 def string_at(ptr, size=0):
404 """string_at(addr[, size]) -> string
406 Return the string at addr."""
407 return _string_at(ptr, size)
409 try:
410 from _ctypes import _wstring_at_addr
411 except ImportError:
412 pass
413 else:
414 _wstring_at = CFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
415 def wstring_at(ptr, size=0):
416 """wstring_at(addr[, size]) -> string
418 Return the string at addr."""
419 return _wstring_at(ptr, size)
422 if _os.name == "nt": # COM stuff
423 def DllGetClassObject(rclsid, riid, ppv):
424 # First ask ctypes.com.server than comtypes.server for the
425 # class object.
427 # trick py2exe by doing dynamic imports
428 result = -2147221231 # CLASS_E_CLASSNOTAVAILABLE
429 try:
430 ctcom = __import__("ctypes.com.server", globals(), locals(), ['*'])
431 except ImportError:
432 pass
433 else:
434 result = ctcom.DllGetClassObject(rclsid, riid, ppv)
436 if result == -2147221231: # CLASS_E_CLASSNOTAVAILABLE
437 try:
438 ccom = __import__("comtypes.server", globals(), locals(), ['*'])
439 except ImportError:
440 pass
441 else:
442 result = ccom.DllGetClassObject(rclsid, riid, ppv)
444 return result
446 def DllCanUnloadNow():
447 # First ask ctypes.com.server than comtypes.server if we can unload or not.
448 # trick py2exe by doing dynamic imports
449 result = 0 # S_OK
450 try:
451 ctcom = __import__("ctypes.com.server", globals(), locals(), ['*'])
452 except ImportError:
453 pass
454 else:
455 result = ctcom.DllCanUnloadNow()
456 if result != 0: # != S_OK
457 return result
459 try:
460 ccom = __import__("comtypes.server", globals(), locals(), ['*'])
461 except ImportError:
462 return result
463 try:
464 return ccom.DllCanUnloadNow()
465 except AttributeError:
466 pass
467 return result
469 from ctypes._endian import BigEndianStructure, LittleEndianStructure
471 # Fill in specifically-sized types
472 c_int8 = c_byte
473 c_uint8 = c_ubyte
474 for kind in [c_short, c_int, c_long, c_longlong]:
475 if sizeof(kind) == 2: c_int16 = kind
476 elif sizeof(kind) == 4: c_int32 = kind
477 elif sizeof(kind) == 8: c_int64 = kind
478 for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
479 if sizeof(kind) == 2: c_uint16 = kind
480 elif sizeof(kind) == 4: c_uint32 = kind
481 elif sizeof(kind) == 8: c_uint64 = kind
482 del(kind)