1 ######################################################################
2 # This file should be kept compatible with Python 2.3, see PEP 291. #
3 ######################################################################
4 """create and manipulate C data types in Python"""
6 import os
as _os
, sys
as _sys
10 from _ctypes
import Union
, Structure
, Array
11 from _ctypes
import _Pointer
12 from _ctypes
import CFuncPtr
as _CFuncPtr
13 from _ctypes
import __version__
as _ctypes_version
14 from _ctypes
import RTLD_LOCAL
, RTLD_GLOBAL
15 from _ctypes
import ArgumentError
17 from struct
import calcsize
as _calcsize
19 if __version__
!= _ctypes_version
:
20 raise Exception("Version number mismatch", __version__
, _ctypes_version
)
22 if _os
.name
in ("nt", "ce"):
23 from _ctypes
import FormatError
25 DEFAULT_MODE
= RTLD_LOCAL
26 if _os
.name
== "posix" and _sys
.platform
== "darwin":
27 # On OS X 10.3, we use RTLD_GLOBAL as default mode
28 # because RTLD_LOCAL does not work at least on some
29 # libraries. OS X 10.3 is Darwin 7, so we check for
32 if int(_os
.uname()[2].split('.')[0]) < 8:
33 DEFAULT_MODE
= RTLD_GLOBAL
35 from _ctypes
import FUNCFLAG_CDECL
as _FUNCFLAG_CDECL
, \
36 FUNCFLAG_PYTHONAPI
as _FUNCFLAG_PYTHONAPI
, \
37 FUNCFLAG_USE_ERRNO
as _FUNCFLAG_USE_ERRNO
, \
38 FUNCFLAG_USE_LASTERROR
as _FUNCFLAG_USE_LASTERROR
47 STDMETHOD_(type, name)
52 def create_string_buffer(init
, size
=None):
53 """create_string_buffer(aString) -> character array
54 create_string_buffer(anInteger) -> character array
55 create_string_buffer(aString, anInteger) -> character array
57 if isinstance(init
, (str, unicode)):
60 buftype
= c_char
* size
64 elif isinstance(init
, (int, long)):
65 buftype
= c_char
* init
70 def c_buffer(init
, size
=None):
71 ## "deprecated, use create_string_buffer instead"
73 ## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
74 ## DeprecationWarning, stacklevel=2)
75 return create_string_buffer(init
, size
)
77 _c_functype_cache
= {}
78 def CFUNCTYPE(restype
, *argtypes
, **kw
):
79 """CFUNCTYPE(restype, *argtypes,
80 use_errno=False, use_last_error=False) -> function prototype.
82 restype: the result type
83 argtypes: a sequence specifying the argument types
85 The function prototype can be called in different ways to create a
88 prototype(integer address) -> foreign function
89 prototype(callable) -> create and return a C callable function from callable
90 prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
91 prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
92 prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
94 flags
= _FUNCFLAG_CDECL
95 if kw
.pop("use_errno", False):
96 flags |
= _FUNCFLAG_USE_ERRNO
97 if kw
.pop("use_last_error", False):
98 flags |
= _FUNCFLAG_USE_LASTERROR
100 raise ValueError("unexpected keyword argument(s) %s" % kw
.keys())
102 return _c_functype_cache
[(restype
, argtypes
, flags
)]
104 class CFunctionType(_CFuncPtr
):
105 _argtypes_
= argtypes
108 _c_functype_cache
[(restype
, argtypes
, flags
)] = CFunctionType
111 if _os
.name
in ("nt", "ce"):
112 from _ctypes
import LoadLibrary
as _dlopen
113 from _ctypes
import FUNCFLAG_STDCALL
as _FUNCFLAG_STDCALL
115 # 'ce' doesn't have the stdcall calling convention
116 _FUNCFLAG_STDCALL
= _FUNCFLAG_CDECL
118 _win_functype_cache
= {}
119 def WINFUNCTYPE(restype
, *argtypes
, **kw
):
120 # docstring set later (very similar to CFUNCTYPE.__doc__)
121 flags
= _FUNCFLAG_STDCALL
122 if kw
.pop("use_errno", False):
123 flags |
= _FUNCFLAG_USE_ERRNO
124 if kw
.pop("use_last_error", False):
125 flags |
= _FUNCFLAG_USE_LASTERROR
127 raise ValueError("unexpected keyword argument(s) %s" % kw
.keys())
129 return _win_functype_cache
[(restype
, argtypes
, flags
)]
131 class WinFunctionType(_CFuncPtr
):
132 _argtypes_
= argtypes
135 _win_functype_cache
[(restype
, argtypes
, flags
)] = WinFunctionType
136 return WinFunctionType
137 if WINFUNCTYPE
.__doc
__:
138 WINFUNCTYPE
.__doc
__ = CFUNCTYPE
.__doc
__.replace("CFUNCTYPE", "WINFUNCTYPE")
140 elif _os
.name
== "posix":
141 from _ctypes
import dlopen
as _dlopen
143 from _ctypes
import sizeof
, byref
, addressof
, alignment
, resize
144 from _ctypes
import get_errno
, set_errno
145 from _ctypes
import _SimpleCData
147 def _check_size(typ
, typecode
=None):
148 # Check if sizeof(ctypes_type) against struct.calcsize. This
149 # should protect somewhat against a misconfigured libffi.
150 from struct
import calcsize
152 # Most _type_ codes are the same as used in struct
153 typecode
= typ
._type
_
154 actual
, required
= sizeof(typ
), calcsize(typecode
)
155 if actual
!= required
:
156 raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
157 (typ
, actual
, required
))
159 class py_object(_SimpleCData
):
163 return super(py_object
, self
).__repr
__()
165 return "%s(<NULL>)" % type(self
).__name
__
166 _check_size(py_object
, "P")
168 class c_short(_SimpleCData
):
172 class c_ushort(_SimpleCData
):
174 _check_size(c_ushort
)
176 class c_long(_SimpleCData
):
180 class c_ulong(_SimpleCData
):
184 if _calcsize("i") == _calcsize("l"):
185 # if int and long have the same size, make c_int an alias for c_long
189 class c_int(_SimpleCData
):
193 class c_uint(_SimpleCData
):
197 class c_float(_SimpleCData
):
201 class c_double(_SimpleCData
):
203 _check_size(c_double
)
205 class c_longdouble(_SimpleCData
):
207 if sizeof(c_longdouble
) == sizeof(c_double
):
208 c_longdouble
= c_double
210 if _calcsize("l") == _calcsize("q"):
211 # if long and long long have the same size, make c_longlong an alias for c_long
213 c_ulonglong
= c_ulong
215 class c_longlong(_SimpleCData
):
217 _check_size(c_longlong
)
219 class c_ulonglong(_SimpleCData
):
221 ## def from_param(cls, val):
222 ## return ('d', float(val), val)
223 ## from_param = classmethod(from_param)
224 _check_size(c_ulonglong
)
226 class c_ubyte(_SimpleCData
):
228 c_ubyte
.__ctype
_le
__ = c_ubyte
.__ctype
_be
__ = c_ubyte
229 # backward compatibility:
233 class c_byte(_SimpleCData
):
235 c_byte
.__ctype
_le
__ = c_byte
.__ctype
_be
__ = c_byte
238 class c_char(_SimpleCData
):
240 c_char
.__ctype
_le
__ = c_char
.__ctype
_be
__ = c_char
243 class c_char_p(_SimpleCData
):
247 if not windll
.kernel32
.IsBadStringPtrA(self
, -1):
248 return "%s(%r)" % (self
.__class
__.__name
__, self
.value
)
249 return "%s(%s)" % (self
.__class
__.__name
__, cast(self
, c_void_p
).value
)
252 return "%s(%s)" % (self
.__class
__.__name
__, cast(self
, c_void_p
).value
)
253 _check_size(c_char_p
, "P")
255 class c_void_p(_SimpleCData
):
257 c_voidp
= c_void_p
# backwards compatibility (to a bug)
258 _check_size(c_void_p
)
260 class c_bool(_SimpleCData
):
263 from _ctypes
import POINTER
, pointer
, _pointer_type_cache
266 from _ctypes
import set_conversion_mode
270 if _os
.name
in ("nt", "ce"):
271 set_conversion_mode("mbcs", "ignore")
273 set_conversion_mode("ascii", "strict")
275 class c_wchar_p(_SimpleCData
):
278 class c_wchar(_SimpleCData
):
281 POINTER(c_wchar
).from_param
= c_wchar_p
.from_param
#_SimpleCData.c_wchar_p_from_param
283 def create_unicode_buffer(init
, size
=None):
284 """create_unicode_buffer(aString) -> character array
285 create_unicode_buffer(anInteger) -> character array
286 create_unicode_buffer(aString, anInteger) -> character array
288 if isinstance(init
, (str, unicode)):
291 buftype
= c_wchar
* size
295 elif isinstance(init
, (int, long)):
296 buftype
= c_wchar
* init
299 raise TypeError(init
)
301 POINTER(c_char
).from_param
= c_char_p
.from_param
#_SimpleCData.c_char_p_from_param
304 def SetPointerType(pointer
, cls
):
305 if _pointer_type_cache
.get(cls
, None) is not None:
306 raise RuntimeError("This type already exists in the cache")
307 if id(pointer
) not in _pointer_type_cache
:
308 raise RuntimeError("What's this???")
309 pointer
.set_type(cls
)
310 _pointer_type_cache
[cls
] = pointer
311 del _pointer_type_cache
[id(pointer
)]
317 ################################################################
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).
325 The exported functions can be accessed as attributes, or by
326 indexing with the function name. Examples:
328 <obj>.qsort -> callable object
329 <obj>['qsort'] -> callable object
331 Calling the functions releases the Python GIL during the call and
332 reacquires it afterwards.
334 _func_flags_
= _FUNCFLAG_CDECL
335 _func_restype_
= c_int
337 def __init__(self
, name
, mode
=DEFAULT_MODE
, handle
=None,
339 use_last_error
=False):
341 flags
= self
._func
_flags
_
343 flags |
= _FUNCFLAG_USE_ERRNO
345 flags |
= _FUNCFLAG_USE_LASTERROR
347 class _FuncPtr(_CFuncPtr
):
349 _restype_
= self
._func
_restype
_
350 self
._FuncPtr
= _FuncPtr
353 self
._handle
= _dlopen(self
._name
, mode
)
355 self
._handle
= handle
358 return "<%s '%s', handle %x at %x>" % \
359 (self
.__class
__.__name
__, self
._name
,
360 (self
._handle
& (_sys
.maxint
*2 + 1)),
361 id(self
) & (_sys
.maxint
*2 + 1))
363 def __getattr__(self
, name
):
364 if name
.startswith('__') and name
.endswith('__'):
365 raise AttributeError(name
)
366 func
= self
.__getitem
__(name
)
367 setattr(self
, name
, func
)
370 def __getitem__(self
, name_or_ordinal
):
371 func
= self
._FuncPtr
((name_or_ordinal
, self
))
372 if not isinstance(name_or_ordinal
, (int, long)):
373 func
.__name
__ = name_or_ordinal
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.
381 _func_flags_
= _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
383 if _os
.name
in ("nt", "ce"):
386 """This class represents a dll exporting functions using the
387 Windows stdcall calling convention.
389 _func_flags_
= _FUNCFLAG_STDCALL
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
):
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.
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
405 _check_retval_
= _check_HRESULT
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
413 _func_flags_
= _FUNCFLAG_STDCALL
414 _func_restype_
= HRESULT
416 class LibraryLoader(object):
417 def __init__(self
, dlltype
):
418 self
._dlltype
= dlltype
420 def __getattr__(self
, name
):
422 raise AttributeError(name
)
423 dll
= self
._dlltype
(name
)
424 setattr(self
, name
, dll
)
427 def __getitem__(self
, name
):
428 return getattr(self
, name
)
430 def LoadLibrary(self
, name
):
431 return self
._dlltype
(name
)
433 cdll
= LibraryLoader(CDLL
)
434 pydll
= LibraryLoader(PyDLL
)
436 if _os
.name
in ("nt", "ce"):
437 pythonapi
= PyDLL("python dll", None, _sys
.dllhandle
)
438 elif _sys
.platform
== "cygwin":
439 pythonapi
= PyDLL("libpython%d.%d.dll" % _sys
.version_info
[:2])
441 pythonapi
= PyDLL(None)
444 if _os
.name
in ("nt", "ce"):
445 windll
= LibraryLoader(WinDLL
)
446 oledll
= LibraryLoader(OleDLL
)
449 GetLastError
= windll
.kernel32
.GetLastError
451 GetLastError
= windll
.coredll
.GetLastError
452 from _ctypes
import get_last_error
, set_last_error
454 def WinError(code
=None, descr
=None):
456 code
= GetLastError()
458 descr
= FormatError(code
).strip()
459 return WindowsError(code
, descr
)
461 _pointer_type_cache
[None] = c_void_p
463 if sizeof(c_uint
) == sizeof(c_void_p
):
465 elif sizeof(c_ulong
) == sizeof(c_void_p
):
467 elif sizeof(c_ulonglong
) == sizeof(c_void_p
):
468 c_size_t
= c_ulonglong
472 from _ctypes
import _memmove_addr
, _memset_addr
, _string_at_addr
, _cast_addr
474 ## void *memmove(void *, const void *, size_t);
475 memmove
= CFUNCTYPE(c_void_p
, c_void_p
, c_void_p
, c_size_t
)(_memmove_addr
)
477 ## void *memset(void *, int, size_t)
478 memset
= CFUNCTYPE(c_void_p
, c_void_p
, c_int
, c_size_t
)(_memset_addr
)
480 def PYFUNCTYPE(restype
, *argtypes
):
481 class CFunctionType(_CFuncPtr
):
482 _argtypes_
= argtypes
484 _flags_
= _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
487 _cast
= PYFUNCTYPE(py_object
, c_void_p
, py_object
, py_object
)(_cast_addr
)
489 return _cast(obj
, obj
, typ
)
491 _string_at
= PYFUNCTYPE(py_object
, c_void_p
, c_int
)(_string_at_addr
)
492 def string_at(ptr
, size
=-1):
493 """string_at(addr[, size]) -> string
495 Return the string at addr."""
496 return _string_at(ptr
, size
)
499 from _ctypes
import _wstring_at_addr
503 _wstring_at
= PYFUNCTYPE(py_object
, c_void_p
, c_int
)(_wstring_at_addr
)
504 def wstring_at(ptr
, size
=-1):
505 """wstring_at(addr[, size]) -> string
507 Return the string at addr."""
508 return _wstring_at(ptr
, size
)
511 if _os
.name
in ("nt", "ce"): # COM stuff
512 def DllGetClassObject(rclsid
, riid
, ppv
):
514 ccom
= __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
516 return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
518 return ccom
.DllGetClassObject(rclsid
, riid
, ppv
)
520 def DllCanUnloadNow():
522 ccom
= __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
525 return ccom
.DllCanUnloadNow()
527 from ctypes
._endian
import BigEndianStructure
, LittleEndianStructure
529 # Fill in specifically-sized types
532 for kind
in [c_short
, c_int
, c_long
, c_longlong
]:
533 if sizeof(kind
) == 2: c_int16
= kind
534 elif sizeof(kind
) == 4: c_int32
= kind
535 elif sizeof(kind
) == 8: c_int64
= kind
536 for kind
in [c_ushort
, c_uint
, c_ulong
, c_ulonglong
]:
537 if sizeof(kind
) == 2: c_uint16
= kind
538 elif sizeof(kind
) == 4: c_uint32
= kind
539 elif sizeof(kind
) == 8: c_uint64
= kind
542 # XXX for whatever reasons, creating the first instance of a callback
543 # function is needed for the unittests on Win64 to succeed. This MAY
544 # be a compiler bug, since the problem occurs only when _ctypes is
545 # compiled with the MS SDK compiler. Or an uninitialized variable?
546 CFUNCTYPE(c_int
)(lambda: None)