Author: Armin Rigo <[email protected]>
Branch:
Changeset: r1092:fe7746226762
Date: 2012-11-30 15:31 -0800
http://bitbucket.org/cffi/cffi/changeset/fe7746226762/
Log: Accept Python strings or random pointers for a "void *" function
argument.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1915,8 +1915,7 @@
if (PyBytes_Check(init)) {
/* from a string: just returning the string here is fine.
We assume that the C code won't modify the 'char *' data. */
- if ((ctitem->ct_flags & CT_PRIMITIVE_CHAR) &&
- (ctitem->ct_size == sizeof(char))) {
+ if (ctptr->ct_flags & CT_CAST_ANYTHING) {
output_data[0] = PyBytes_AS_STRING(init);
return 1;
}
@@ -4676,6 +4675,11 @@
return result;
}
+static int _testfunc23(char *p)
+{
+ return 1000 * p[0];
+}
+
static PyObject *b__testfunc(PyObject *self, PyObject *args)
{
/* for testing only */
@@ -4707,6 +4711,7 @@
case 20: f = &_testfunc20; break;
case 21: f = &_testfunc21; break;
case 22: f = &_testfunc22; break;
+ case 23: f = &_testfunc23; break;
default:
PyErr_SetNone(PyExc_ValueError);
return NULL;
@@ -4754,7 +4759,7 @@
if (CData_Check(obj)) {
return ((CDataObject *)obj)->c_data;
}
- _convert_error(obj, "char *", "compatible pointer");
+ _convert_error(obj, "char * or void *", "compatible pointer");
return NULL;
}
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -992,6 +992,15 @@
for i in range(10):
assert res.a[i] == p1.a[i] - p2.a[i]
+def test_call_function_23():
+ BVoid = new_void_type() # declaring the function as int(void*)
+ BVoidP = new_pointer_type(BVoid)
+ BInt = new_primitive_type("int")
+ BFunc23 = new_function_type((BVoidP,), BInt, False)
+ f = cast(BFunc23, _testfunc(23))
+ res = f(b"foo")
+ assert res == 1000 * ord(b'f')
+
def test_cannot_pass_struct_with_array_of_length_0():
BInt = new_primitive_type("int")
BArray0 = new_array_type(new_pointer_type(BInt), 0)
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -201,8 +201,9 @@
errvalue = '-1'
#
elif isinstance(tp, model.PointerType):
- if (isinstance(tp.totype, model.PrimitiveType) and
- tp.totype.name == 'char'):
+ if ((isinstance(tp.totype, model.PrimitiveType) and
+ tp.totype.name == 'char') or
+ isinstance(tp.totype, model.VoidType)):
converter = '_cffi_to_c_char_p'
else:
converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('')
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -1423,3 +1423,17 @@
"int myfunc(enum foo_e x) { return (int)x; }")
res = lib2.myfunc("AA")
assert res == 2
+
+def test_string_to_voidp_arg():
+ ffi = FFI()
+ ffi.cdef("int myfunc(void *);")
+ lib = ffi.verify("int myfunc(void *p) { return ((signed char *)p)[0]; }")
+ res = lib.myfunc(b"hi!")
+ assert res == ord(b"h")
+ p = ffi.new("char[]", b"gah")
+ res = lib.myfunc(p)
+ assert res == ord(b"g")
+ res = lib.myfunc(ffi.cast("void *", p))
+ assert res == ord(b"g")
+ res = lib.myfunc(ffi.cast("int *", p))
+ assert res == ord(b"g")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit