[pypy-svn] r50747 - in pypy/dist/pypy/lib: _ctypes app_test/ctypes

fijal at codespeak.net fijal at codespeak.net
Fri Jan 18 12:38:36 CET 2008


Author: fijal
Date: Fri Jan 18 12:38:35 2008
New Revision: 50747

Modified:
   pypy/dist/pypy/lib/_ctypes/primitive.py
   pypy/dist/pypy/lib/app_test/ctypes/test_pointers.py
Log:
(cfbolz, fijal)

Automatically cast byref() results to c_void_p, when c_void_p is expected
as function argument.



Modified: pypy/dist/pypy/lib/_ctypes/primitive.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/primitive.py	(original)
+++ pypy/dist/pypy/lib/_ctypes/primitive.py	Fri Jan 18 12:38:35 2008
@@ -83,12 +83,12 @@
                 self._buffer[0] = value
             result.value = property(_getvalue, _setvalue)            
         
-        if tp == 'z' or tp == 'P':
+        if tp == 'z':
             from _ctypes import Array, _Pointer
-            # c_char_p and c_void_p
+            # c_char_p
             def from_param(self, value):
                 if value is None:
-                    return None
+                    return self(None)
                 if isinstance(value, basestring):
                     return self(value)
                 if isinstance(value, _SimpleCData) and \
@@ -101,6 +101,26 @@
                         return value
                 return SimpleType.from_param(self, value)
             result.from_param = classmethod(from_param)
+        elif tp == 'P':
+            from _ctypes import Array, _Pointer
+            # c_void_p
+            def from_param(self, value):
+                if value is None:
+                    return self(None)
+                if isinstance(value, basestring):
+                    return self(value)
+                if isinstance(value, _SimpleCData) and \
+                       type(value)._type_ in 'zP':
+                    return value
+                if isinstance(value, Array):
+                    from ctypes import c_char, c_byte
+                    if type(value)._type_ == c_char or \
+                           type(value)._type_ == c_byte:
+                        return value
+                if isinstance(value, _Pointer):
+                    return self.from_address(value._buffer.buffer)
+                return SimpleType.from_param(self, value)
+            result.from_param = classmethod(from_param)
 
         return result
 

Modified: pypy/dist/pypy/lib/app_test/ctypes/test_pointers.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_pointers.py	(original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_pointers.py	Fri Jan 18 12:38:35 2008
@@ -235,3 +235,16 @@
 
         py.test.raises(TypeError, c_void_p, 3.14) # make sure floats are NOT accepted
         py.test.raises(TypeError, c_void_p, object()) # nor other objects
+
+    def test_c_char_p_byref(self):
+        dll = CDLL(_ctypes_test)
+        TwoOutArgs = dll.TwoOutArgs
+        TwoOutArgs.restype = None
+        TwoOutArgs.argtypes = [c_int, c_void_p, c_int, c_void_p]
+        a = c_int(3)
+        b = c_int(4)
+        c = c_int(5)
+        d = c_int(6)
+        TwoOutArgs(a, byref(b), c, byref(d))
+        assert b.value == 7
+        assert d.value == 11



More information about the Pypy-commit mailing list