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
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, ))
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()
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
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
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, ))
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()
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, ))
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()
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
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
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, ))