Beispiel #1
0
 def _call_funcptr(self, funcptr, *newargs):
     if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
         tmp = _rawffi.get_errno()
         _rawffi.set_errno(get_errno())
         set_errno(tmp)
     if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
         tmp = _rawffi.get_last_error()
         _rawffi.set_last_error(get_last_error())
         set_last_error(tmp)
     try:
         result = funcptr(*newargs)
     finally:
         if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
             tmp = _rawffi.get_errno()
             _rawffi.set_errno(get_errno())
             set_errno(tmp)
         if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
             tmp = _rawffi.get_last_error()
             _rawffi.set_last_error(get_last_error())
             set_last_error(tmp)
     #
     try:
         return self._build_result(self._restype_, result)
     finally:
         funcptr.free_temp_buffers()
Beispiel #2
0
    def _call_funcptr(self, funcptr, *newargs):

        if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
            tmp = _rawffi.get_errno()
            _rawffi.set_errno(get_errno())
            set_errno(tmp)
        if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
            tmp = _rawffi.get_last_error()
            _rawffi.set_last_error(get_last_error())
            set_last_error(tmp)
        try:
            result = funcptr(*newargs)
        finally:
            if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
                tmp = _rawffi.get_errno()
                _rawffi.set_errno(get_errno())
                set_errno(tmp)
            if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
                tmp = _rawffi.get_last_error()
                _rawffi.set_last_error(get_last_error())
                set_last_error(tmp)
        #
        try:
            return self._build_result(self._restype_, result)
        finally:
            funcptr.free_temp_buffers()
Beispiel #3
0
 def test_errno_saved_and_restored(self):
     def check():
         assert _rawffi.get_errno() == 42
         assert ctypes.get_errno() == old
     check.free_temp_buffers = lambda *args: None
     f = function.CFuncPtr()
     old = _rawffi.get_errno()
     f._flags_ = _rawffi.FUNCFLAG_USE_ERRNO
     ctypes.set_errno(42)
     f._call_funcptr(check)
     assert _rawffi.get_errno() == old
     ctypes.set_errno(0)
Beispiel #4
0
    def test_errno_saved_and_restored(self):
        def check():
            assert _rawffi.get_errno() == 42
            assert ctypes.get_errno() == old

        check.free_temp_buffers = lambda *args: None
        f = function.CFuncPtr()
        old = _rawffi.get_errno()
        f._flags_ = _rawffi.FUNCFLAG_USE_ERRNO
        ctypes.set_errno(42)
        f._call_funcptr(check)
        assert _rawffi.get_errno() == old
        ctypes.set_errno(0)
Beispiel #5
0
    def _call_funcptr(self, funcptr, *newargs):

        if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
            set_errno(_rawffi.get_errno())
        if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
            set_last_error(_rawffi.get_last_error())
        try:
            result = funcptr(*newargs)
        finally:
            if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
                set_errno(_rawffi.get_errno())
            if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
                set_last_error(_rawffi.get_last_error())
        #
        return self._build_result(self._restype_, result, newargs)
Beispiel #6
0
 def test_errno(self):
     import _rawffi
     lib = _rawffi.CDLL(self.lib_name)
     A = _rawffi.Array('i')
     f = lib.ptr('check_errno', ['i'], 'i')
     _rawffi.set_errno(42)
     arg = A(1)
     arg[0] = 43
     res = f(arg)
     assert res[0] == 42
     z = _rawffi.get_errno()
     assert z == 43
     arg.free()
Beispiel #7
0
 def test_errno(self):
     import _rawffi
     lib = _rawffi.CDLL(self.lib_name)
     A = _rawffi.Array('i')
     f = lib.ptr('check_errno', ['i'], 'i')
     _rawffi.set_errno(42)
     arg = A(1)
     arg[0] = 43
     res = f(arg)
     assert res[0] == 42
     z = _rawffi.get_errno()
     assert z == 43
     arg.free()
Beispiel #8
0
    def __call__(self, *args, **kwargs):
        argtypes = self._argtypes_
        if self.callable is not None:
            if len(args) == len(argtypes):
                pass
            elif self._flags_ & _rawffi.FUNCFLAG_CDECL:
                if len(args) < len(argtypes):
                    plural = len(argtypes) > 1 and "s" or ""
                    raise TypeError(
                        "This function takes at least %d argument%s (%s given)"
                        % (len(argtypes), plural, len(args)))
                else:
                    # For cdecl functions, we allow more actual arguments
                    # than the length of the argtypes tuple.
                    args = args[:len(self._argtypes_)]
            else:
                plural = len(argtypes) > 1 and "s" or ""
                raise TypeError(
                    "This function takes %d argument%s (%s given)" %
                    (len(argtypes), plural, len(args)))

            # check that arguments are convertible
            ## XXX Not as long as ctypes.cast is a callback function with
            ## py_object arguments...
            ## self._convert_args(argtypes, args, {})

            try:
                res = self.callable(*args)
            except:
                exc_info = sys.exc_info()
                traceback.print_tb(exc_info[2], file=sys.stderr)
                print >> sys.stderr, "%s: %s" % (exc_info[0].__name__,
                                                 exc_info[1])
                return 0
            if self._restype_ is not None:
                return res
            return

        if argtypes is None:
            warnings.warn('C function without declared arguments called',
                          RuntimeWarning,
                          stacklevel=2)
            argtypes = []

        if not self.__restype_set:
            warnings.warn('C function without declared return type called',
                          RuntimeWarning,
                          stacklevel=2)

        if self._com_index:
            from ctypes import cast, c_void_p, POINTER
            if not args:
                raise ValueError(
                    "native COM method call without 'this' parameter")
            thisarg = cast(args[0], POINTER(POINTER(c_void_p))).contents
            argtypes = [c_void_p] + list(argtypes)
            args = list(args)
            args[0] = args[0].value
        else:
            thisarg = None

        args, outargs = self._convert_args(argtypes, args, kwargs)
        argtypes = [type(arg) for arg in args]

        restype = self._restype_
        funcptr = self._getfuncptr(argtypes, restype, thisarg)
        if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
            set_errno(_rawffi.get_errno())
        if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
            set_last_error(_rawffi.get_last_error())
        try:
            resbuffer = funcptr(
                *[arg._get_buffer_for_param()._buffer for arg in args])
        finally:
            if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
                set_errno(_rawffi.get_errno())
            if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
                set_last_error(_rawffi.get_last_error())

        result = None
        if self._com_index:
            if resbuffer[0] & 0x80000000:
                raise get_com_error(resbuffer[0], self._com_iid, args[0])
            else:
                result = int(resbuffer[0])
        elif restype is not None:
            checker = getattr(self.restype, '_check_retval_', None)
            if checker:
                val = restype(resbuffer[0])
                # the original ctypes seems to make the distinction between
                # classes defining a new type, and their subclasses
                if '_type_' in restype.__dict__:
                    val = val.value
                result = checker(val)
            elif not isinstance(restype, _CDataMeta):
                result = restype(resbuffer[0])
            else:
                result = restype._CData_retval(resbuffer)

        # The 'errcheck' protocol
        if self._errcheck_:
            v = self._errcheck_(result, self, args)
            # If the errcheck funtion failed, let it throw
            # If the errcheck function returned callargs unchanged,
            # continue normal processing.
            # If the errcheck function returned something else,
            # use that as result.
            if v is not args:
                result = v

        if not outargs:
            return result

        if len(outargs) == 1:
            return outargs[0]

        return tuple(outargs)
Beispiel #9
0
 def check():
     assert _rawffi.get_errno() == 42
     assert ctypes.get_errno() == old
Beispiel #10
0
    def __call__(self, *args, **kwargs):
        argtypes = self._argtypes_
        if self.callable is not None:
            if len(args) == len(argtypes):
                pass
            elif self._flags_ & _rawffi.FUNCFLAG_CDECL:
                if len(args) < len(argtypes):
                    plural = len(argtypes) > 1 and "s" or ""
                    raise TypeError(
                        "This function takes at least %d argument%s (%s given)"
                        % (len(argtypes), plural, len(args)))
                else:
                    # For cdecl functions, we allow more actual arguments
                    # than the length of the argtypes tuple.
                    args = args[:len(self._argtypes_)]
            else:
                plural = len(argtypes) > 1 and "s" or ""
                raise TypeError(
                    "This function takes %d argument%s (%s given)"
                    % (len(argtypes), plural, len(args)))

            # check that arguments are convertible
            ## XXX Not as long as ctypes.cast is a callback function with
            ## py_object arguments...
            ## self._convert_args(argtypes, args, {})

            try:
                res = self.callable(*args)
            except:
                exc_info = sys.exc_info()
                traceback.print_tb(exc_info[2], file=sys.stderr)
                print >>sys.stderr, "%s: %s" % (exc_info[0].__name__, exc_info[1])
                return 0
            if self._restype_ is not None:
                return res
            return

        if argtypes is None:
            warnings.warn('C function without declared arguments called',
                          RuntimeWarning, stacklevel=2)
            argtypes = []
            
        if not self.__restype_set:
            warnings.warn('C function without declared return type called',
                          RuntimeWarning, stacklevel=2)

        if self._com_index:
            from ctypes import cast, c_void_p, POINTER
            if not args:
                raise ValueError(
                    "native COM method call without 'this' parameter"
                    )
            thisarg = cast(args[0], POINTER(POINTER(c_void_p))).contents
            argtypes = [c_void_p] + list(argtypes)
            args = list(args)
            args[0] = args[0].value
        else:
            thisarg = None

        args, outargs = self._convert_args(argtypes, args, kwargs)
        argtypes = [type(arg) for arg in args]

        restype = self._restype_
        funcptr = self._getfuncptr(argtypes, restype, thisarg)
        if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
            set_errno(_rawffi.get_errno())
        if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
            set_last_error(_rawffi.get_last_error())
        try:
            resbuffer = funcptr(*[arg._get_buffer_for_param()._buffer
                                  for arg in args])
        finally:
            if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
                set_errno(_rawffi.get_errno())
            if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
                set_last_error(_rawffi.get_last_error())

        result = None
        if self._com_index:
            if resbuffer[0] & 0x80000000:
                raise get_com_error(resbuffer[0],
                                    self._com_iid, args[0])
            else:
                result = int(resbuffer[0])
        elif restype is not None:
            checker = getattr(self.restype, '_check_retval_', None)
            if checker:
                val = restype(resbuffer[0])
                # the original ctypes seems to make the distinction between
                # classes defining a new type, and their subclasses
                if '_type_' in restype.__dict__:
                    val = val.value
                result = checker(val)
            elif not isinstance(restype, _CDataMeta):
                result = restype(resbuffer[0])
            else:
                result = restype._CData_retval(resbuffer)

        # The 'errcheck' protocol
        if self._errcheck_:
            v = self._errcheck_(result, self, args)
            # If the errcheck funtion failed, let it throw
            # If the errcheck function returned callargs unchanged,
            # continue normal processing.
            # If the errcheck function returned something else,
            # use that as result.
            if v is not args:
                result = v

        if not outargs:
            return result

        if len(outargs) == 1:
            return outargs[0]

        return tuple(outargs)
Beispiel #11
0
 def check():
     assert _rawffi.get_errno() == 42
     assert ctypes.get_errno() == old