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
45 STDMETHOD_(type, name)
50 def create_string_buffer(init
, size
=None):
51 """create_string_buffer(aString) -> character array
52 create_string_buffer(anInteger) -> character array
53 create_string_buffer(aString, anInteger) -> character array
55 if isinstance(init
, (str, unicode)):
58 buftype
= c_char
* size
62 elif isinstance(init
, (int, long)):
63 buftype
= c_char
* init
68 def c_buffer(init
, size
=None):
69 ## "deprecated, use create_string_buffer instead"
71 ## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
72 ## DeprecationWarning, stacklevel=2)
73 return create_string_buffer(init
, size
)
75 _c_functype_cache
= {}
76 def CFUNCTYPE(restype
, *argtypes
):
77 """CFUNCTYPE(restype, *argtypes) -> function prototype.
79 restype: the result type
80 argtypes: a sequence specifying the argument types
82 The function prototype can be called in different ways to create a
85 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
92 return _c_functype_cache
[(restype
, argtypes
)]
94 class CFunctionType(_CFuncPtr
):
97 _flags_
= _FUNCFLAG_CDECL
98 _c_functype_cache
[(restype
, argtypes
)] = CFunctionType
101 if _os
.name
in ("nt", "ce"):
102 from _ctypes
import LoadLibrary
as _dlopen
103 from _ctypes
import FUNCFLAG_STDCALL
as _FUNCFLAG_STDCALL
105 # 'ce' doesn't have the stdcall calling convention
106 _FUNCFLAG_STDCALL
= _FUNCFLAG_CDECL
108 _win_functype_cache
= {}
109 def WINFUNCTYPE(restype
, *argtypes
):
110 # docstring set later (very similar to CFUNCTYPE.__doc__)
112 return _win_functype_cache
[(restype
, argtypes
)]
114 class WinFunctionType(_CFuncPtr
):
115 _argtypes_
= argtypes
117 _flags_
= _FUNCFLAG_STDCALL
118 _win_functype_cache
[(restype
, argtypes
)] = WinFunctionType
119 return WinFunctionType
120 if WINFUNCTYPE
.__doc
__:
121 WINFUNCTYPE
.__doc
__ = CFUNCTYPE
.__doc
__.replace("CFUNCTYPE", "WINFUNCTYPE")
123 elif _os
.name
== "posix":
124 from _ctypes
import dlopen
as _dlopen
126 from _ctypes
import sizeof
, byref
, addressof
, alignment
, resize
127 from _ctypes
import _SimpleCData
129 def _check_size(typ
, typecode
=None):
130 # Check if sizeof(ctypes_type) against struct.calcsize. This
131 # should protect somewhat against a misconfigured libffi.
132 from struct
import calcsize
134 # Most _type_ codes are the same as used in struct
135 typecode
= typ
._type
_
136 actual
, required
= sizeof(typ
), calcsize(typecode
)
137 if actual
!= required
:
138 raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
139 (typ
, actual
, required
))
141 class py_object(_SimpleCData
):
145 return super(py_object
, self
).__repr
__()
147 return "%s(<NULL>)" % type(self
).__name
__
148 _check_size(py_object
, "P")
150 class c_short(_SimpleCData
):
154 class c_ushort(_SimpleCData
):
156 _check_size(c_ushort
)
158 class c_long(_SimpleCData
):
162 class c_ulong(_SimpleCData
):
166 if _calcsize("i") == _calcsize("l"):
167 # if int and long have the same size, make c_int an alias for c_long
171 class c_int(_SimpleCData
):
175 class c_uint(_SimpleCData
):
179 class c_float(_SimpleCData
):
183 class c_double(_SimpleCData
):
185 _check_size(c_double
)
187 class c_longdouble(_SimpleCData
):
189 if sizeof(c_longdouble
) == sizeof(c_double
):
190 c_longdouble
= c_double
192 if _calcsize("l") == _calcsize("q"):
193 # if long and long long have the same size, make c_longlong an alias for c_long
195 c_ulonglong
= c_ulong
197 class c_longlong(_SimpleCData
):
199 _check_size(c_longlong
)
201 class c_ulonglong(_SimpleCData
):
203 ## def from_param(cls, val):
204 ## return ('d', float(val), val)
205 ## from_param = classmethod(from_param)
206 _check_size(c_ulonglong
)
208 class c_ubyte(_SimpleCData
):
210 c_ubyte
.__ctype
_le
__ = c_ubyte
.__ctype
_be
__ = c_ubyte
211 # backward compatibility:
215 class c_byte(_SimpleCData
):
217 c_byte
.__ctype
_le
__ = c_byte
.__ctype
_be
__ = c_byte
220 class c_char(_SimpleCData
):
222 c_char
.__ctype
_le
__ = c_char
.__ctype
_be
__ = c_char
225 class c_char_p(_SimpleCData
):
229 if not windll
.kernel32
.IsBadStringPtrA(self
, -1):
230 return "%s(%r)" % (self
.__class
__.__name
__, self
.value
)
231 return "%s(%s)" % (self
.__class
__.__name
__, cast(self
, c_void_p
).value
)
234 return "%s(%s)" % (self
.__class
__.__name
__, cast(self
, c_void_p
).value
)
235 _check_size(c_char_p
, "P")
237 class c_void_p(_SimpleCData
):
239 c_voidp
= c_void_p
# backwards compatibility (to a bug)
240 _check_size(c_void_p
)
242 class c_bool(_SimpleCData
):
245 from _ctypes
import POINTER
, pointer
, _pointer_type_cache
248 from _ctypes
import set_conversion_mode
252 if _os
.name
in ("nt", "ce"):
253 set_conversion_mode("mbcs", "ignore")
255 set_conversion_mode("ascii", "strict")
257 class c_wchar_p(_SimpleCData
):
260 class c_wchar(_SimpleCData
):
263 POINTER(c_wchar
).from_param
= c_wchar_p
.from_param
#_SimpleCData.c_wchar_p_from_param
265 def create_unicode_buffer(init
, size
=None):
266 """create_unicode_buffer(aString) -> character array
267 create_unicode_buffer(anInteger) -> character array
268 create_unicode_buffer(aString, anInteger) -> character array
270 if isinstance(init
, (str, unicode)):
273 buftype
= c_wchar
* size
277 elif isinstance(init
, (int, long)):
278 buftype
= c_wchar
* init
281 raise TypeError(init
)
283 POINTER(c_char
).from_param
= c_char_p
.from_param
#_SimpleCData.c_char_p_from_param
286 def SetPointerType(pointer
, cls
):
287 if _pointer_type_cache
.get(cls
, None) is not None:
288 raise RuntimeError("This type already exists in the cache")
289 if id(pointer
) not in _pointer_type_cache
:
290 raise RuntimeError("What's this???")
291 pointer
.set_type(cls
)
292 _pointer_type_cache
[cls
] = pointer
293 del _pointer_type_cache
[id(pointer
)]
299 ################################################################
303 """An instance of this class represents a loaded dll/shared
304 library, exporting functions using the standard C calling
305 convention (named 'cdecl' on Windows).
307 The exported functions can be accessed as attributes, or by
308 indexing with the function name. Examples:
310 <obj>.qsort -> callable object
311 <obj>['qsort'] -> callable object
313 Calling the functions releases the Python GIL during the call and
314 reacquires it afterwards.
316 class _FuncPtr(_CFuncPtr
):
317 _flags_
= _FUNCFLAG_CDECL
318 _restype_
= c_int
# default, can be overridden in instances
320 def __init__(self
, name
, mode
=DEFAULT_MODE
, handle
=None):
323 self
._handle
= _dlopen(self
._name
, mode
)
325 self
._handle
= handle
328 return "<%s '%s', handle %x at %x>" % \
329 (self
.__class
__.__name
__, self
._name
,
330 (self
._handle
& (_sys
.maxint
*2 + 1)),
331 id(self
) & (_sys
.maxint
*2 + 1))
333 def __getattr__(self
, name
):
334 if name
.startswith('__') and name
.endswith('__'):
335 raise AttributeError(name
)
336 func
= self
.__getitem
__(name
)
337 setattr(self
, name
, func
)
340 def __getitem__(self
, name_or_ordinal
):
341 func
= self
._FuncPtr
((name_or_ordinal
, self
))
342 if not isinstance(name_or_ordinal
, (int, long)):
343 func
.__name
__ = name_or_ordinal
347 """This class represents the Python library itself. It allows to
348 access Python API functions. The GIL is not released, and
349 Python exceptions are handled correctly.
351 class _FuncPtr(_CFuncPtr
):
352 _flags_
= _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
353 _restype_
= c_int
# default, can be overridden in instances
355 if _os
.name
in ("nt", "ce"):
358 """This class represents a dll exporting functions using the
359 Windows stdcall calling convention.
361 class _FuncPtr(_CFuncPtr
):
362 _flags_
= _FUNCFLAG_STDCALL
363 _restype_
= c_int
# default, can be overridden in instances
365 # XXX Hm, what about HRESULT as normal parameter?
366 # Mustn't it derive from c_long then?
367 from _ctypes
import _check_HRESULT
, _SimpleCData
368 class HRESULT(_SimpleCData
):
370 # _check_retval_ is called with the function's result when it
371 # is used as restype. It checks for the FAILED bit, and
372 # raises a WindowsError if it is set.
374 # The _check_retval_ method is implemented in C, so that the
375 # method definition itself is not included in the traceback
376 # when it raises an error - that is what we want (and Python
377 # doesn't have a way to raise an exception in the caller's
379 _check_retval_
= _check_HRESULT
382 """This class represents a dll exporting functions using the
383 Windows stdcall calling convention, and returning HRESULT.
384 HRESULT error values are automatically raised as WindowsError
387 class _FuncPtr(_CFuncPtr
):
388 _flags_
= _FUNCFLAG_STDCALL
391 class LibraryLoader(object):
392 def __init__(self
, dlltype
):
393 self
._dlltype
= dlltype
395 def __getattr__(self
, name
):
397 raise AttributeError(name
)
398 dll
= self
._dlltype
(name
)
399 setattr(self
, name
, dll
)
402 def __getitem__(self
, name
):
403 return getattr(self
, name
)
405 def LoadLibrary(self
, name
):
406 return self
._dlltype
(name
)
408 cdll
= LibraryLoader(CDLL
)
409 pydll
= LibraryLoader(PyDLL
)
411 if _os
.name
in ("nt", "ce"):
412 pythonapi
= PyDLL("python dll", None, _sys
.dllhandle
)
413 elif _sys
.platform
== "cygwin":
414 pythonapi
= PyDLL("libpython%d.%d.dll" % _sys
.version_info
[:2])
416 pythonapi
= PyDLL(None)
419 if _os
.name
in ("nt", "ce"):
420 windll
= LibraryLoader(WinDLL
)
421 oledll
= LibraryLoader(OleDLL
)
424 GetLastError
= windll
.kernel32
.GetLastError
426 GetLastError
= windll
.coredll
.GetLastError
428 def WinError(code
=None, descr
=None):
430 code
= GetLastError()
432 descr
= FormatError(code
).strip()
433 return WindowsError(code
, descr
)
435 _pointer_type_cache
[None] = c_void_p
437 if sizeof(c_uint
) == sizeof(c_void_p
):
439 elif sizeof(c_ulong
) == sizeof(c_void_p
):
441 elif sizeof(c_ulonglong
) == sizeof(c_void_p
):
442 c_size_t
= c_ulonglong
446 from _ctypes
import _memmove_addr
, _memset_addr
, _string_at_addr
, _cast_addr
448 ## void *memmove(void *, const void *, size_t);
449 memmove
= CFUNCTYPE(c_void_p
, c_void_p
, c_void_p
, c_size_t
)(_memmove_addr
)
451 ## void *memset(void *, int, size_t)
452 memset
= CFUNCTYPE(c_void_p
, c_void_p
, c_int
, c_size_t
)(_memset_addr
)
454 def PYFUNCTYPE(restype
, *argtypes
):
455 class CFunctionType(_CFuncPtr
):
456 _argtypes_
= argtypes
458 _flags_
= _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
461 _cast
= PYFUNCTYPE(py_object
, c_void_p
, py_object
, py_object
)(_cast_addr
)
463 return _cast(obj
, obj
, typ
)
465 _string_at
= CFUNCTYPE(py_object
, c_void_p
, c_int
)(_string_at_addr
)
466 def string_at(ptr
, size
=-1):
467 """string_at(addr[, size]) -> string
469 Return the string at addr."""
470 return _string_at(ptr
, size
)
473 from _ctypes
import _wstring_at_addr
477 _wstring_at
= CFUNCTYPE(py_object
, c_void_p
, c_int
)(_wstring_at_addr
)
478 def wstring_at(ptr
, size
=-1):
479 """wstring_at(addr[, size]) -> string
481 Return the string at addr."""
482 return _wstring_at(ptr
, size
)
485 if _os
.name
in ("nt", "ce"): # COM stuff
486 def DllGetClassObject(rclsid
, riid
, ppv
):
488 ccom
= __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
490 return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
492 return ccom
.DllGetClassObject(rclsid
, riid
, ppv
)
494 def DllCanUnloadNow():
496 ccom
= __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
499 return ccom
.DllCanUnloadNow()
501 from ctypes
._endian
import BigEndianStructure
, LittleEndianStructure
503 # Fill in specifically-sized types
506 for kind
in [c_short
, c_int
, c_long
, c_longlong
]:
507 if sizeof(kind
) == 2: c_int16
= kind
508 elif sizeof(kind
) == 4: c_int32
= kind
509 elif sizeof(kind
) == 8: c_int64
= kind
510 for kind
in [c_ushort
, c_uint
, c_ulong
, c_ulonglong
]:
511 if sizeof(kind
) == 2: c_uint16
= kind
512 elif sizeof(kind
) == 4: c_uint32
= kind
513 elif sizeof(kind
) == 8: c_uint64
= kind
516 # XXX for whatever reasons, creating the first instance of a callback
517 # function is needed for the unittests on Win64 to succeed. This MAY
518 # be a compiler bug, since the problem occurs only when _ctypes is
519 # compiled with the MS SDK compiler. Or an uninitialized variable?
520 CFUNCTYPE(c_int
)(lambda: None)