This class extends ctypes.CDLL with automatic checking of errno and automatically raises an exception when set by the function.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import ctypes
class CDLL_errno(ctypes.CDLL):
    class _FuncPtr(ctypes._CFuncPtr):
        _flags_ = ctypes._FUNCFLAG_CDECL | ctypes._FUNCFLAG_USE_ERRNO
        _restype_ = ctypes.c_int
        def __call__(self, *args):
            ctypes.set_errno(0)
            try:
                return ctypes._CFuncPtr.__call__(self, *args)
            finally:
                errno = ctypes.get_errno()
                if errno:
                    import os
                    raise IOError(errno, os.strerror(errno))
    def __init__(self, *args, **kw):
        ctypes.CDLL.__init__(self, *args, **kw)
        del self._FuncPtr
 | 
The ctypes modules provides a useful feature for Windows users: if a DLL contains function that follow the calling convention of returning HRESULT you can use the WinDLL() class to load it. This installs a _check_retval_ checker for the function result and when is != S_OK it will automatically raise a WindowsError exception and automatically set the error code and description.
For POSIX there is no single standard value to indicate that errno should be checked. For some functions it is a null pointer. For others it is -1, etc. This means that a _check_retval_ checker cannot be used to implement such automatic exception handling.
This class works around this limitation by wrapping __call__ instead of using _check_retval_. Before the call errno is zeroed and if it is non-zero after the call an exception is raised.

 Download
Download Copy to clipboard
Copy to clipboard

Why del self._FuncPtr :
The CDLL.__init__ sets a _FuncPtr as an instance member. Deleting it re-exposes the one in this class.