[pypy-commit] cffi default: More general fix for returning pointers from callbacks in ctypes backend.
tlynn
noreply at buildbot.pypy.org
Wed Jun 20 12:41:02 CEST 2012
Author: tlynn
Branch:
Changeset: r475:8eb01069d65f
Date: 2012-06-19 21:03 +0100
http://bitbucket.org/cffi/cffi/changeset/8eb01069d65f/
Log: More general fix for returning pointers from callbacks in ctypes
backend.
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -673,11 +673,23 @@
args2.append(BArg._from_ctypes(arg))
res2 = init(*args2)
res2 = BResult._to_ctypes(res2)
- if isinstance(res2, ctypes.c_void_p):
- # workaround for http://bugs.python.org/issue1574593
- res2 = res2.value
+ 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
- self._as_ctype_ptr = CTypesFunction._ctype(callback)
+ 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
@@ -566,6 +566,28 @@
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