예제 #1
0
 def test_callback(self):
     import _rawffi
     oldnum = _rawffi._num_of_allocated_objects()
     c = _rawffi.CallbackPtr(lambda : 3, [], 'i')
     assert _rawffi._num_of_allocated_objects() - oldnum== 1
     c.free()
     assert _rawffi._num_of_allocated_objects() - oldnum== 0
예제 #2
0
파일: function.py 프로젝트: chyyuu/pygirl
 def __init__(self, argument=None):
     self.callable = None
     self.name = None
     self._objects = {keepalive_key(0): self}
     if isinstance(argument, int):
         self._buffer = _rawffi.Array('P').fromaddress(argument, 1)
         # XXX finish this one, we need to be able to jump there somehow
     elif callable(argument):
         self.callable = argument
         argtypes = [arg._ffiargshape for arg in self._argtypes_]
         restype = self._restype_._ffiletter
         self._ptr = _rawffi.CallbackPtr(argument, argtypes, restype)
         self._needs_free = True
         self._buffer = self._ptr.byptr()
     elif isinstance(argument, tuple) and len(argument) == 2:
         import ctypes
         self.name, self.dll = argument
         if isinstance(self.dll, str):
             self.dll = ctypes.CDLL(self.dll)
         # we need to check dll anyway
         self._getfuncptr([], ctypes.c_int)
     elif argument is None:
         return  # needed for test..
     else:
         raise TypeError("Unknown constructor %s" % (argument, ))
예제 #3
0
 def test_callback(self):
     import _rawffi
     import struct
     libc = _rawffi.get_libc()
     ll_to_sort = _rawffi.Array('i')(4)
     for i in range(4):
         ll_to_sort[i] = 4-i
     qsort = libc.ptr('qsort', ['P', 'l', 'l', 'P'], None)
     bogus_args = []
     def compare(a, b):
         a1 = _rawffi.Array('i').fromaddress(_rawffi.Array('P').fromaddress(a, 1)[0], 1)
         a2 = _rawffi.Array('i').fromaddress(_rawffi.Array('P').fromaddress(b, 1)[0], 1)
         if a1[0] not in [1,2,3,4] or a2[0] not in [1,2,3,4]:
             bogus_args.append((a1[0], a2[0]))
         if a1[0] > a2[0]:
             return 1
         return -1
     a1 = ll_to_sort.byptr()
     a2 = _rawffi.Array('l')(1)
     a2[0] = len(ll_to_sort)
     a3 = _rawffi.Array('l')(1)
     a3[0] = struct.calcsize('i')
     cb = _rawffi.CallbackPtr(compare, ['P', 'P'], 'l')
     a4 = cb.byptr()
     qsort(a1, a2, a3, a4)
     res = [ll_to_sort[i] for i in range(len(ll_to_sort))]
     assert res == [1,2,3,4]
     assert not bogus_args
     a1.free()
     a2.free()
     a3.free()
     a4.free()
     ll_to_sort.free()
     cb.free()
예제 #4
0
    def test_callback(self):
        import _rawffi
        import struct
        libc = _rawffi.CDLL('libc.so.6')
        ll_to_sort = _rawffi.Array('i')(4)
        for i in range(4):
            ll_to_sort[i] = 4 - i
        qsort = libc.ptr('qsort', ['P', 'i', 'i', 'P'], None)
        resarray = _rawffi.Array('i')(1)

        def compare(a, b):
            a1 = _rawffi.Array('i').fromaddress(a, 1)
            a2 = _rawffi.Array('i').fromaddress(b, 1)
            if a1[0] > a2[0]:
                res = -1
            res = 1
            return res

        a1 = ll_to_sort.byptr()
        a2 = _rawffi.Array('i')(1)
        a2[0] = len(ll_to_sort)
        a3 = _rawffi.Array('i')(1)
        a3[0] = struct.calcsize('i')
        cb = _rawffi.CallbackPtr(compare, ['P', 'P'], 'i')
        a4 = cb.byptr()
        qsort(a1, a2, a3, a4)
        res = [ll_to_sort[i] for i in range(len(ll_to_sort))]
        assert res == [1, 2, 3, 4]
        a1.free()
        a2.free()
        a3.free()
        a4.free()
        ll_to_sort.free()
        del cb
예제 #5
0
    def test_another_callback_in_stackless(self):
        try:
            import _stackless
        except ImportError:
            skip("only valid in a stackless pypy-c")

        import _rawffi
        lib = _rawffi.CDLL(self.lib_name)
        runcallback = lib.ptr('runcallback', ['P'], 'q')

        def callback():
            co = _stackless.coroutine()

            def f():
                pass

            try:
                co.bind(f)
                co.switch()
            except RuntimeError:
                return 1 << 42
            return -5

        cb = _rawffi.CallbackPtr(callback, [], 'q')
        a1 = cb.byptr()
        res = runcallback(a1)
        assert res[0] == 1 << 42
        a1.free()
        del cb
예제 #6
0
 def __init__(self, argument=None):
     self.name = None
     self._objects = {keepalive_key(0): self}
     self._needs_free = True
     if isinstance(argument, (int, long)):
         ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
         self._ptr = _rawffi.FuncPtr(argument, ffiargs, ffires)
         self._buffer = self._ptr.byptr()
     elif callable(argument):
         self.callable = argument
         ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
         self._ptr = _rawffi.CallbackPtr(
             self._wrap_callable(argument, self.argtypes), ffiargs, ffires)
         self._buffer = self._ptr.byptr()
     elif isinstance(argument, tuple) and len(argument) == 2:
         import ctypes
         self.name, self.dll = argument
         if isinstance(self.dll, str):
             self.dll = ctypes.CDLL(self.dll)
         # we need to check dll anyway
         ptr = self._getfuncptr([], ctypes.c_int)
         self._buffer = ptr.byptr()
     elif argument is None:
         # this is needed for casts
         self._buffer = _rawffi.Array('P')(1)
         return
     else:
         raise TypeError("Unknown constructor %s" % (argument, ))
예제 #7
0
    def test_another_callback(self):
        import _rawffi
        lib = _rawffi.CDLL(self.lib_name)
        runcallback = lib.ptr('runcallback', ['P'], 'q')
        def callback():
            return 1<<42

        cb = _rawffi.CallbackPtr(callback, [], 'q')
        a1 = cb.byptr()
        res = runcallback(a1)
        assert res[0] == 1<<42
        a1.free()
        cb.free()
예제 #8
0
    def __init__(self, *args):
        self.name = None
        self._objects = {keepalive_key(0): self}
        self._needs_free = True
        argument = None
        if len(args) == 1:
            argument = args[0]

        if isinstance(argument, (int, long)):
            # direct construction from raw address
            ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
            self._ptr = _rawffi.FuncPtr(argument, ffiargs, ffires,
                                        self._flags_)
            self._buffer = self._ptr.byptr()
        elif callable(argument):
            # A callback into python
            self.callable = argument
            ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
            self._ptr = _rawffi.CallbackPtr(
                self._wrap_callable(argument, self.argtypes), ffiargs, ffires,
                self._flags_)
            self._buffer = self._ptr.byptr()
        elif isinstance(argument, tuple) and len(argument) == 2:
            # function exported from a shared library
            import ctypes
            self.name, self.dll = argument
            if isinstance(self.dll, str):
                self.dll = ctypes.CDLL(self.dll)
            # we need to check dll anyway
            ptr = self._getfuncptr([], ctypes.c_int)
            self._buffer = ptr.byptr()

        elif (sys.platform == 'win32' and len(args) >= 2
              and isinstance(args[0], (int, long))):
            # A COM function call, by index
            ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
            self._com_index = args[0] + 0x1000
            self.name = args[1]
            if len(args) > 2:
                self._paramflags = args[2]
            # XXX ignored iid = args[3]

        elif len(args) == 0:
            # Empty function object.
            # this is needed for casts
            self._buffer = _rawffi.Array('P')(1)
            return
        else:
            raise TypeError("Unknown constructor %s" % (args, ))
예제 #9
0
    def test_void_returning_callback(self):
        import _rawffi
        lib = _rawffi.CDLL(self.lib_name)
        runcallback = lib.ptr('runcallback', ['P'], None)
        called = []
        def callback():
            called.append(True)

        cb = _rawffi.CallbackPtr(callback, [], None)
        a1 = cb.byptr()
        res = runcallback(a1)
        assert res is None
        assert called == [True]
        a1.free()
        cb.free()
예제 #10
0
    def test_callback_struct_byvalue(self):
        import _rawffi, sys
        X_Y = _rawffi.Structure([('x', 'l'), ('y', 'l')])
        lib = _rawffi.CDLL(self.lib_name)
        op_x_y = lib.ptr('op_x_y', [(X_Y, 1), 'P'], 'l')

        def callback(x_y):
            return x_y.x + x_y.y
        cb = _rawffi.CallbackPtr(callback, [(X_Y, 1)], 'l')

        x_y = X_Y()
        x_y.x = 200
        x_y.y = 220

        a1 = cb.byptr()
        res = op_x_y(x_y, a1)
        a1.free()
        x_y.free()
        cb.free()

        assert res[0] == 420
예제 #11
0
    def test_raising_callback(self):
        import _rawffi, sys
        import StringIO
        lib = _rawffi.CDLL(self.lib_name)
        err = StringIO.StringIO()
        orig = sys.stderr
        sys.stderr = err
        try:
            runcallback = lib.ptr('runcallback', ['P'], 'q')

            def callback():
                1 / 0

            cb = _rawffi.CallbackPtr(callback, [], 'q')
            a1 = cb.byptr()
            res = runcallback(a1)
            a1.free()
            del cb
            val = err.getvalue()
            assert 'ZeroDivisionError' in val
            assert 'callback' in val
        finally:
            sys.stderr = orig
예제 #12
0
    def __init__(self, *args):
        self.name = None
        self._objects = {keepalive_key(0): self}
        self._needs_free = True

        # Empty function object -- this is needed for casts
        if not args:
            self._set_address(0)
            return

        argsl = list(args)
        argument = argsl.pop(0)

        # Direct construction from raw address
        if isinstance(argument, int) and not argsl:
            self._set_address(argument)
            restype = self._restype_
            if restype is None:
                import ctypes
                restype = ctypes.c_int
            if self._argtypes_ is None:
                self._argtypes_ = []
            self._ptr = self._getfuncptr_fromaddress(self._argtypes_, restype)
            return

        # A callback into python
        if callable(argument) and not argsl:
            self.callable = argument
            ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
            if self._restype_ is None:
                ffires = None
            self._ptr = _rawffi.CallbackPtr(
                self._wrap_callable(argument, self.argtypes), ffiargs, ffires,
                self._flags_)
            self._buffer = self._ptr.byptr()
            return

        # Function exported from a shared library
        if isinstance(argument, tuple) and len(argument) == 2:
            import ctypes
            self.name, dll = argument
            if isinstance(dll, str):
                self.dll = ctypes.CDLL(self.dll)
            else:
                self.dll = dll
            if argsl:
                self.paramflags = argsl.pop(0)
                if argsl:
                    raise TypeError("Unknown constructor %s" % (args, ))
            # We need to check dll anyway
            ptr = self._getfuncptr([], ctypes.c_int)
            self._set_address(ptr.getaddr())
            return

        # A COM function call, by index
        if (sys.platform == 'win32' and isinstance(argument, int) and argsl):
            ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
            self._com_index = argument + 0x1000
            self.name = argsl.pop(0)
            if argsl:
                self.paramflags = argsl.pop(0)
                if argsl:
                    self._com_iid = argsl.pop(0)
                    if argsl:
                        raise TypeError("Unknown constructor %s" % (args, ))
            return

        raise TypeError("Unknown constructor %s" % (args, ))