[pypy-commit] cffi default: Merged in tlynn/cffi (pull request #2)

arigo noreply at buildbot.pypy.org
Wed Jun 20 12:41:03 CEST 2012


Author: arigo <armin.rigo at gmail.com>
Branch: 
Changeset: r476:a3c6a07b8257
Date: 2012-06-20 12:40 +0200
http://bitbucket.org/cffi/cffi/changeset/a3c6a07b8257/

Log:	Merged in tlynn/cffi (pull request #2)

diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -672,8 +672,24 @@
                     for arg, BArg in zip(args, BArgs):
                         args2.append(BArg._from_ctypes(arg))
                     res2 = init(*args2)
-                    return BResult._to_ctypes(res2)
-                self._as_ctype_ptr = CTypesFunction._ctype(callback)
+                    res2 = BResult._to_ctypes(res2)
+                    if issubclass(BResult, CTypesGenericPtr):
+                        if res2:
+                            res2 = ctypes.cast(res2, ctypes.c_void_p).value
+                                # .value: http://bugs.python.org/issue1574593
+                        else:
+                            res2 = None
+                    return res2
+                if issubclass(BResult, CTypesGenericPtr):
+                    # The only pointers callbacks can return are void*s:
+                    # http://bugs.python.org/issue5710
+                    callback_ctype = ctypes.CFUNCTYPE(
+                        ctypes.c_void_p,
+                        *[BArg._ctype for BArg in BArgs],
+                        use_errno=True)
+                else:
+                    callback_ctype = CTypesFunction._ctype
+                self._as_ctype_ptr = callback_ctype(callback)
                 self._address = ctypes.cast(self._as_ctype_ptr,
                                             ctypes.c_void_p).value
                 self._own_callback = init
diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -550,6 +550,44 @@
         t = ffi.typeof("int(*(*)(int))(int)")
         assert repr(t) == self.TypeRepr % "int(*(*)(int))(int)"
 
+    def test_functionptr_voidptr_return(self):
+        ffi = FFI(backend=self.Backend())
+        def cb():
+            return None
+        p = ffi.callback("void*(*)()", cb)
+        res = p()
+        assert res is None
+        int_ptr = ffi.new('int')
+        void_ptr = ffi.cast('void*', int_ptr)
+        def cb():
+            return void_ptr
+        p = ffi.callback("void*(*)()", cb)
+        res = p()
+        assert repr(res) == "<cdata 'void *'>"
+        assert ffi.cast("long", res) != 0
+
+    def test_functionptr_intptr_return(self):
+        ffi = FFI(backend=self.Backend())
+        def cb():
+            return None
+        p = ffi.callback("int*(*)()", cb)
+        res = p()
+        assert res is None
+        int_ptr = ffi.new('int')
+        def cb():
+            return int_ptr
+        p = ffi.callback("int*(*)()", cb)
+        res = p()
+        assert repr(res) == "<cdata 'int *'>"
+        assert ffi.cast("long", res) != 0
+        int_array_ptr = ffi.new('int[1]')
+        def cb():
+            return int_array_ptr
+        p = ffi.callback("int*(*)()", cb)
+        res = p()
+        assert repr(res) == "<cdata 'int *'>"
+        assert ffi.cast("long", res) != 0
+
     def test_char_cast(self):
         ffi = FFI(backend=self.Backend())
         p = ffi.cast("int", '\x01')


More information about the pypy-commit mailing list