Home | History | Annotate | Download | only in ctypes
      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"""
      5 
      6 import os as _os, sys as _sys
      7 
      8 __version__ = "1.1.0"
      9 
     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
     16 
     17 from struct import calcsize as _calcsize
     18 
     19 if __version__ != _ctypes_version:
     20     raise Exception("Version number mismatch", __version__, _ctypes_version)
     21 
     22 if _os.name in ("nt", "ce"):
     23     from _ctypes import FormatError
     24 
     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
     30     # that.
     31 
     32     if int(_os.uname()[2].split('.')[0]) < 8:
     33         DEFAULT_MODE = RTLD_GLOBAL
     34 
     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
     39 
     40 """
     41 WINOLEAPI -> HRESULT
     42 WINOLEAPI_(type)
     43 
     44 STDMETHODCALLTYPE
     45 
     46 STDMETHOD(name)
     47 STDMETHOD_(type, name)
     48 
     49 STDAPICALLTYPE
     50 """
     51 
     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
     56     """
     57     if isinstance(init, (str, unicode)):
     58         if size is None:
     59             size = len(init)+1
     60         buftype = c_char * size
     61         buf = buftype()
     62         buf.value = init
     63         return buf
     64     elif isinstance(init, (int, long)):
     65         buftype = c_char * init
     66         buf = buftype()
     67         return buf
     68     raise TypeError(init)
     69 
     70 def c_buffer(init, size=None):
     71 ##    "deprecated, use create_string_buffer instead"
     72 ##    import warnings
     73 ##    warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
     74 ##                  DeprecationWarning, stacklevel=2)
     75     return create_string_buffer(init, size)
     76 
     77 _c_functype_cache = {}
     78 def CFUNCTYPE(restype, *argtypes, **kw):
     79     """CFUNCTYPE(restype, *argtypes,
     80                  use_errno=False, use_last_error=False) -> function prototype.
     81 
     82     restype: the result type
     83     argtypes: a sequence specifying the argument types
     84 
     85     The function prototype can be called in different ways to create a
     86     callable object:
     87 
     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
     93     """
     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
     99     if kw:
    100         raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
    101     try:
    102         return _c_functype_cache[(restype, argtypes, flags)]
    103     except KeyError:
    104         class CFunctionType(_CFuncPtr):
    105             _argtypes_ = argtypes
    106             _restype_ = restype
    107             _flags_ = flags
    108         _c_functype_cache[(restype, argtypes, flags)] = CFunctionType
    109         return CFunctionType
    110 
    111 if _os.name in ("nt", "ce"):
    112     from _ctypes import LoadLibrary as _dlopen
    113     from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
    114     if _os.name == "ce":
    115         # 'ce' doesn't have the stdcall calling convention
    116         _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
    117 
    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
    126         if kw:
    127             raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
    128         try:
    129             return _win_functype_cache[(restype, argtypes, flags)]
    130         except KeyError:
    131             class WinFunctionType(_CFuncPtr):
    132                 _argtypes_ = argtypes
    133                 _restype_ = restype
    134                 _flags_ = flags
    135             _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType
    136             return WinFunctionType
    137     if WINFUNCTYPE.__doc__:
    138         WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
    139 
    140 elif _os.name == "posix":
    141     from _ctypes import dlopen as _dlopen
    142 
    143 from _ctypes import sizeof, byref, addressof, alignment, resize
    144 from _ctypes import get_errno, set_errno
    145 from _ctypes import _SimpleCData
    146 
    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
    151     if typecode is None:
    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))
    158 
    159 class py_object(_SimpleCData):
    160     _type_ = "O"
    161     def __repr__(self):
    162         try:
    163             return super(py_object, self).__repr__()
    164         except ValueError:
    165             return "%s(<NULL>)" % type(self).__name__
    166 _check_size(py_object, "P")
    167 
    168 class c_short(_SimpleCData):
    169     _type_ = "h"
    170 _check_size(c_short)
    171 
    172 class c_ushort(_SimpleCData):
    173     _type_ = "H"
    174 _check_size(c_ushort)
    175 
    176 class c_long(_SimpleCData):
    177     _type_ = "l"
    178 _check_size(c_long)
    179 
    180 class c_ulong(_SimpleCData):
    181     _type_ = "L"
    182 _check_size(c_ulong)
    183 
    184 if _calcsize("i") == _calcsize("l"):
    185     # if int and long have the same size, make c_int an alias for c_long
    186     c_int = c_long
    187     c_uint = c_ulong
    188 else:
    189     class c_int(_SimpleCData):
    190         _type_ = "i"
    191     _check_size(c_int)
    192 
    193     class c_uint(_SimpleCData):
    194         _type_ = "I"
    195     _check_size(c_uint)
    196 
    197 class c_float(_SimpleCData):
    198     _type_ = "f"
    199 _check_size(c_float)
    200 
    201 class c_double(_SimpleCData):
    202     _type_ = "d"
    203 _check_size(c_double)
    204 
    205 class c_longdouble(_SimpleCData):
    206     _type_ = "g"
    207 if sizeof(c_longdouble) == sizeof(c_double):
    208     c_longdouble = c_double
    209 
    210 if _calcsize("l") == _calcsize("q"):
    211     # if long and long long have the same size, make c_longlong an alias for c_long
    212     c_longlong = c_long
    213     c_ulonglong = c_ulong
    214 else:
    215     class c_longlong(_SimpleCData):
    216         _type_ = "q"
    217     _check_size(c_longlong)
    218 
    219     class c_ulonglong(_SimpleCData):
    220         _type_ = "Q"
    221     ##    def from_param(cls, val):
    222     ##        return ('d', float(val), val)
    223     ##    from_param = classmethod(from_param)
    224     _check_size(c_ulonglong)
    225 
    226 class c_ubyte(_SimpleCData):
    227     _type_ = "B"
    228 c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
    229 # backward compatibility:
    230 ##c_uchar = c_ubyte
    231 _check_size(c_ubyte)
    232 
    233 class c_byte(_SimpleCData):
    234     _type_ = "b"
    235 c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
    236 _check_size(c_byte)
    237 
    238 class c_char(_SimpleCData):
    239     _type_ = "c"
    240 c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
    241 _check_size(c_char)
    242 
    243 class c_char_p(_SimpleCData):
    244     _type_ = "z"
    245     if _os.name == "nt":
    246         def __repr__(self):
    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)
    250     else:
    251         def __repr__(self):
    252             return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
    253 _check_size(c_char_p, "P")
    254 
    255 class c_void_p(_SimpleCData):
    256     _type_ = "P"
    257 c_voidp = c_void_p # backwards compatibility (to a bug)
    258 _check_size(c_void_p)
    259 
    260 class c_bool(_SimpleCData):
    261     _type_ = "?"
    262 
    263 from _ctypes import POINTER, pointer, _pointer_type_cache
    264 
    265 def _reset_cache():
    266     _pointer_type_cache.clear()
    267     _c_functype_cache.clear()
    268     if _os.name in ("nt", "ce"):
    269         _win_functype_cache.clear()
    270     # _SimpleCData.c_wchar_p_from_param
    271     POINTER(c_wchar).from_param = c_wchar_p.from_param
    272     # _SimpleCData.c_char_p_from_param
    273     POINTER(c_char).from_param = c_char_p.from_param
    274     _pointer_type_cache[None] = c_void_p
    275     # XXX for whatever reasons, creating the first instance of a callback
    276     # function is needed for the unittests on Win64 to succeed.  This MAY
    277     # be a compiler bug, since the problem occurs only when _ctypes is
    278     # compiled with the MS SDK compiler.  Or an uninitialized variable?
    279     CFUNCTYPE(c_int)(lambda: None)
    280 
    281 try:
    282     from _ctypes import set_conversion_mode
    283 except ImportError:
    284     pass
    285 else:
    286     if _os.name in ("nt", "ce"):
    287         set_conversion_mode("mbcs", "ignore")
    288     else:
    289         set_conversion_mode("ascii", "strict")
    290 
    291     class c_wchar_p(_SimpleCData):
    292         _type_ = "Z"
    293 
    294     class c_wchar(_SimpleCData):
    295         _type_ = "u"
    296 
    297     def create_unicode_buffer(init, size=None):
    298         """create_unicode_buffer(aString) -> character array
    299         create_unicode_buffer(anInteger) -> character array
    300         create_unicode_buffer(aString, anInteger) -> character array
    301         """
    302         if isinstance(init, (str, unicode)):
    303             if size is None:
    304                 size = len(init)+1
    305             buftype = c_wchar * size
    306             buf = buftype()
    307             buf.value = init
    308             return buf
    309         elif isinstance(init, (int, long)):
    310             buftype = c_wchar * init
    311             buf = buftype()
    312             return buf
    313         raise TypeError(init)
    314 
    315 # XXX Deprecated
    316 def SetPointerType(pointer, cls):
    317     if _pointer_type_cache.get(cls, None) is not None:
    318         raise RuntimeError("This type already exists in the cache")
    319     if id(pointer) not in _pointer_type_cache:
    320         raise RuntimeError("What's this???")
    321     pointer.set_type(cls)
    322     _pointer_type_cache[cls] = pointer
    323     del _pointer_type_cache[id(pointer)]
    324 
    325 # XXX Deprecated
    326 def ARRAY(typ, len):
    327     return typ * len
    328 
    329 ################################################################
    330 
    331 
    332 class CDLL(object):
    333     """An instance of this class represents a loaded dll/shared
    334     library, exporting functions using the standard C calling
    335     convention (named 'cdecl' on Windows).
    336 
    337     The exported functions can be accessed as attributes, or by
    338     indexing with the function name.  Examples:
    339 
    340     <obj>.qsort -> callable object
    341     <obj>['qsort'] -> callable object
    342 
    343     Calling the functions releases the Python GIL during the call and
    344     reacquires it afterwards.
    345     """
    346     _func_flags_ = _FUNCFLAG_CDECL
    347     _func_restype_ = c_int
    348 
    349     def __init__(self, name, mode=DEFAULT_MODE, handle=None,
    350                  use_errno=False,
    351                  use_last_error=False):
    352         self._name = name
    353         flags = self._func_flags_
    354         if use_errno:
    355             flags |= _FUNCFLAG_USE_ERRNO
    356         if use_last_error:
    357             flags |= _FUNCFLAG_USE_LASTERROR
    358 
    359         class _FuncPtr(_CFuncPtr):
    360             _flags_ = flags
    361             _restype_ = self._func_restype_
    362         self._FuncPtr = _FuncPtr
    363 
    364         if handle is None:
    365             self._handle = _dlopen(self._name, mode)
    366         else:
    367             self._handle = handle
    368 
    369     def __repr__(self):
    370         return "<%s '%s', handle %x at %x>" % \
    371                (self.__class__.__name__, self._name,
    372                 (self._handle & (_sys.maxint*2 + 1)),
    373                 id(self) & (_sys.maxint*2 + 1))
    374 
    375     def __getattr__(self, name):
    376         if name.startswith('__') and name.endswith('__'):
    377             raise AttributeError(name)
    378         func = self.__getitem__(name)
    379         setattr(self, name, func)
    380         return func
    381 
    382     def __getitem__(self, name_or_ordinal):
    383         func = self._FuncPtr((name_or_ordinal, self))
    384         if not isinstance(name_or_ordinal, (int, long)):
    385             func.__name__ = name_or_ordinal
    386         return func
    387 
    388 class PyDLL(CDLL):
    389     """This class represents the Python library itself.  It allows to
    390     access Python API functions.  The GIL is not released, and
    391     Python exceptions are handled correctly.
    392     """
    393     _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
    394 
    395 if _os.name in ("nt", "ce"):
    396 
    397     class WinDLL(CDLL):
    398         """This class represents a dll exporting functions using the
    399         Windows stdcall calling convention.
    400         """
    401         _func_flags_ = _FUNCFLAG_STDCALL
    402 
    403     # XXX Hm, what about HRESULT as normal parameter?
    404     # Mustn't it derive from c_long then?
    405     from _ctypes import _check_HRESULT, _SimpleCData
    406     class HRESULT(_SimpleCData):
    407         _type_ = "l"
    408         # _check_retval_ is called with the function's result when it
    409         # is used as restype.  It checks for the FAILED bit, and
    410         # raises a WindowsError if it is set.
    411         #
    412         # The _check_retval_ method is implemented in C, so that the
    413         # method definition itself is not included in the traceback
    414         # when it raises an error - that is what we want (and Python
    415         # doesn't have a way to raise an exception in the caller's
    416         # frame).
    417         _check_retval_ = _check_HRESULT
    418 
    419     class OleDLL(CDLL):
    420         """This class represents a dll exporting functions using the
    421         Windows stdcall calling convention, and returning HRESULT.
    422         HRESULT error values are automatically raised as WindowsError
    423         exceptions.
    424         """
    425         _func_flags_ = _FUNCFLAG_STDCALL
    426         _func_restype_ = HRESULT
    427 
    428 class LibraryLoader(object):
    429     def __init__(self, dlltype):
    430         self._dlltype = dlltype
    431 
    432     def __getattr__(self, name):
    433         if name[0] == '_':
    434             raise AttributeError(name)
    435         dll = self._dlltype(name)
    436         setattr(self, name, dll)
    437         return dll
    438 
    439     def __getitem__(self, name):
    440         return getattr(self, name)
    441 
    442     def LoadLibrary(self, name):
    443         return self._dlltype(name)
    444 
    445 cdll = LibraryLoader(CDLL)
    446 pydll = LibraryLoader(PyDLL)
    447 
    448 if _os.name in ("nt", "ce"):
    449     pythonapi = PyDLL("python dll", None, _sys.dllhandle)
    450 elif _sys.platform == "cygwin":
    451     pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
    452 else:
    453     pythonapi = PyDLL(None)
    454 
    455 
    456 if _os.name in ("nt", "ce"):
    457     windll = LibraryLoader(WinDLL)
    458     oledll = LibraryLoader(OleDLL)
    459 
    460     if _os.name == "nt":
    461         GetLastError = windll.kernel32.GetLastError
    462     else:
    463         GetLastError = windll.coredll.GetLastError
    464     from _ctypes import get_last_error, set_last_error
    465 
    466     def WinError(code=None, descr=None):
    467         if code is None:
    468             code = GetLastError()
    469         if descr is None:
    470             descr = FormatError(code).strip()
    471         return WindowsError(code, descr)
    472 
    473 if sizeof(c_uint) == sizeof(c_void_p):
    474     c_size_t = c_uint
    475     c_ssize_t = c_int
    476 elif sizeof(c_ulong) == sizeof(c_void_p):
    477     c_size_t = c_ulong
    478     c_ssize_t = c_long
    479 elif sizeof(c_ulonglong) == sizeof(c_void_p):
    480     c_size_t = c_ulonglong
    481     c_ssize_t = c_longlong
    482 
    483 # functions
    484 
    485 from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
    486 
    487 ## void *memmove(void *, const void *, size_t);
    488 memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
    489 
    490 ## void *memset(void *, int, size_t)
    491 memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
    492 
    493 def PYFUNCTYPE(restype, *argtypes):
    494     class CFunctionType(_CFuncPtr):
    495         _argtypes_ = argtypes
    496         _restype_ = restype
    497         _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
    498     return CFunctionType
    499 
    500 _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
    501 def cast(obj, typ):
    502     return _cast(obj, obj, typ)
    503 
    504 _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
    505 def string_at(ptr, size=-1):
    506     """string_at(addr[, size]) -> string
    507 
    508     Return the string at addr."""
    509     return _string_at(ptr, size)
    510 
    511 try:
    512     from _ctypes import _wstring_at_addr
    513 except ImportError:
    514     pass
    515 else:
    516     _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
    517     def wstring_at(ptr, size=-1):
    518         """wstring_at(addr[, size]) -> string
    519 
    520         Return the string at addr."""
    521         return _wstring_at(ptr, size)
    522 
    523 
    524 if _os.name in ("nt", "ce"): # COM stuff
    525     def DllGetClassObject(rclsid, riid, ppv):
    526         try:
    527             ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
    528         except ImportError:
    529             return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
    530         else:
    531             return ccom.DllGetClassObject(rclsid, riid, ppv)
    532 
    533     def DllCanUnloadNow():
    534         try:
    535             ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
    536         except ImportError:
    537             return 0 # S_OK
    538         return ccom.DllCanUnloadNow()
    539 
    540 from ctypes._endian import BigEndianStructure, LittleEndianStructure
    541 
    542 # Fill in specifically-sized types
    543 c_int8 = c_byte
    544 c_uint8 = c_ubyte
    545 for kind in [c_short, c_int, c_long, c_longlong]:
    546     if sizeof(kind) == 2: c_int16 = kind
    547     elif sizeof(kind) == 4: c_int32 = kind
    548     elif sizeof(kind) == 8: c_int64 = kind
    549 for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
    550     if sizeof(kind) == 2: c_uint16 = kind
    551     elif sizeof(kind) == 4: c_uint32 = kind
    552     elif sizeof(kind) == 8: c_uint64 = kind
    553 del(kind)
    554 
    555 _reset_cache()
    556