Commits

Armin Rigo  committed 5574124

Test and fix in the ctypes backend for calling "void *" functions with a
Python string argument.

  • Participants
  • Parent commits 6ae25e9

Comments (0)

Files changed (2)

File cffi/backend_ctypes.py

         elif BItem in (getbtype(model.PrimitiveType('signed char')),
                        getbtype(model.PrimitiveType('unsigned char'))):
             kind = 'bytep'
+        elif BItem is getbtype(model.void_type):
+            kind = 'voidp'
         else:
             kind = 'generic'
         #
             def __setitem__(self, index, value):
                 self._as_ctype_ptr[index] = BItem._to_ctypes(value)
 
-            if kind == 'charp':
+            if kind == 'charp' or kind == 'voidp':
                 @classmethod
-                def _arg_to_ctypes(cls, value):
-                    if isinstance(value, bytes):
-                        return ctypes.c_char_p(value)
+                def _arg_to_ctypes(cls, *value):
+                    if value and isinstance(value[0], bytes):
+                        return ctypes.c_char_p(value[0])
                     else:
-                        return super(CTypesPtr, cls)._arg_to_ctypes(value)
+                        return super(CTypesPtr, cls)._arg_to_ctypes(*value)
 
             if kind == 'charp' or kind == 'bytep':
                 def _to_string(self, maxlen):

File testing/test_function.py

         assert lib.DD == 6
         assert lib.EE == -5
         assert lib.FF == -4
+
+    def test_void_star_accepts_string(self):
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("""int strlen(const void *);""")
+        lib = ffi.dlopen(None)
+        res = lib.strlen(b"hello")
+        assert res == 5
+
+    def test_signed_char_star_accepts_string(self):
+        if self.Backend is CTypesBackend:
+            py.test.skip("not supported by the ctypes backend")
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("""int strlen(signed char *);""")
+        lib = ffi.dlopen(None)
+        res = lib.strlen(b"hello")
+        assert res == 5
+
+    def test_unsigned_char_star_accepts_string(self):
+        if self.Backend is CTypesBackend:
+            py.test.skip("not supported by the ctypes backend")
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("""int strlen(unsigned char *);""")
+        lib = ffi.dlopen(None)
+        res = lib.strlen(b"hello")
+        assert res == 5