Example #1
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, ))
Example #2
0
    def _getfuncptr(self, argtypes, restype, thisarg=None):
        if self._ptr is not None and argtypes is self._argtypes_:
            return self._ptr
        if restype is None or not isinstance(restype, _CDataMeta):
            import ctypes
            restype = ctypes.c_int
        argshapes = [arg._ffiargshape for arg in argtypes]
        resshape = restype._ffiargshape
        if self._buffer is not None:
            ptr = _rawffi.FuncPtr(self._buffer[0], argshapes, resshape,
                                  self._flags_)
            if argtypes is self._argtypes_:
                self._ptr = ptr
            return ptr

        if self._com_index:
            # extract the address from the object's virtual table
            if not thisarg:
                raise ValueError("COM method call without VTable")
            ptr = thisarg[self._com_index - 0x1000]
            return _rawffi.FuncPtr(ptr, argshapes, resshape, self._flags_)

        cdll = self.dll._handle
        try:
            return cdll.ptr(self.name, argshapes, resshape, self._flags_)
        except AttributeError:
            if self._flags_ & _rawffi.FUNCFLAG_CDECL:
                raise
            # Win64 has no stdcall calling conv, so it should also not have the
            # name mangling of it.
            if WIN64:
                raise
            # For stdcall, try mangled names:
            # funcname -> _funcname@<n>
            # where n is 0, 4, 8, 12, ..., 128
            for i in range(33):
                mangled_name = "_%s@%d" % (self.name, i * 4)
                try:
                    return cdll.ptr(mangled_name, argshapes, resshape,
                                    self._flags_)
                except AttributeError:
                    pass
            raise
Example #3
0
 def _getfuncptr(self, argtypes, restype):
     if self._ptr is not None:
         return self._ptr
     if restype is None or not isinstance(restype, _CDataMeta):
         import ctypes
         restype = ctypes.c_int
     argshapes = [arg._ffiargshape for arg in argtypes]
     resshape = restype._ffiargshape
     if self._buffer is not None:
         self._ptr = _rawffi.FuncPtr(self._buffer[0], argshapes, resshape)
         return self._ptr
     return self.dll._handle.ptr(self.name, argshapes, resshape)
Example #4
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, ))
Example #5
0
 def test_raw_callable(self):
     import _rawffi
     lib = _rawffi.CDLL(self.lib_name)
     get_raw_pointer = lib.ptr('get_raw_pointer', [], 'P')
     ptr = get_raw_pointer()
     rawcall = _rawffi.FuncPtr(ptr[0], ['h', 'h'], 'H')
     A = _rawffi.Array('h')
     arg1 = A(1)
     arg2 = A(1)
     arg1[0] = 1
     arg2[0] = 2
     res = rawcall(arg1, arg2)
     assert res[0] == 3
     arg1.free()
     arg2.free()
     assert rawcall.buffer == ptr[0]
     ptr = rawcall.byptr()
     assert ptr[0] == rawcall.buffer
     ptr.free()
Example #6
0
 def test_raw_callable_returning_void(self):
     import _rawffi
     _rawffi.FuncPtr(0, [], None)
Example #7
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._buffer = _rawffi.Array('P')(1)
            return

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

        # Direct construction from raw address
        if isinstance(argument, (int, long)) and not argsl:
            ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
            self._ptr = _rawffi.FuncPtr(argument, ffiargs, ffires,
                                        self._flags_)
            self._buffer = self._ptr.byptr()
            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(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._buffer = ptr.byptr()
            return

        # A COM function call, by index
        if (sys.platform == 'win32' and isinstance(argument, (int, long))
                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, ))