[pypy-svn] r50518 - pypy/branch/applevel-ctypes2/pypy/lib/_ctypes

fijal at codespeak.net fijal at codespeak.net
Fri Jan 11 15:50:12 CET 2008


Author: fijal
Date: Fri Jan 11 15:50:11 2008
New Revision: 50518

Modified:
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py
   pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py
Log:
Wack enough to make both test_numbers and test_pointer happy.
The solution right now is to create always the intermediate CArgObject
which contains raw reference to what it passes down to _ffi. A lot of
overhead, but works.


Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py	Fri Jan 11 15:50:11 2008
@@ -1,4 +1,5 @@
 import _ffi
+from _ctypes.param import CArgObject
 
 class CFuncPtrType(type):
     # XXX write down here defaults and such things
@@ -30,7 +31,9 @@
             if len(args) != len(self.argtypes):
                 raise TypeError("%s takes %s arguments, given %s" %
                                 (self.name, len(self.argtypes), len(args)))
-        res = self._getfuncptr(args)(*[arg.value for arg in args])
+        funcptr = self._getfuncptr(args)
+        argvalues = [tp.from_param(arg).raw_value for tp, arg in zip(self._argtypes, args)]
+        res = funcptr(*argvalues)
         if issubclass(self.restype, ctypes._SimpleCData):
             return res
         else:
@@ -49,7 +52,7 @@
         argtps = [argtype._ffiletter for argtype in argtypes]
         restp = self.restype._ffiletter
         self._funcptr = funcptr = self.dll._handle.ptr(self.name, argtps, restp)
-        self._argtypes = self.argtypes
+        self._argtypes = argtypes
         self._restype = self.restype
         return funcptr
 
@@ -59,6 +62,8 @@
         for arg in args:
             if isinstance(arg, _ctypes._CData):
                 res.append(type(arg))
+            elif isinstance(arg, CArgObject):
+                res.append(arg._type)
             else:
                 raise TypeError("Cannot convert %s" % arg)
         return res

Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py	Fri Jan 11 15:50:11 2008
@@ -1,6 +1,7 @@
 
 import _ffi
 from _ctypes.basics import _CData
+from _ctypes.param import CArgObject
 
 DEFAULT_VALUE = object()
 
@@ -34,6 +35,13 @@
         obj.__init__ = __init__
         return obj
 
+    def from_param(self, param):
+        # XXX think deeper about that
+        if isinstance(param, CArgObject):
+            return param
+        else:
+            return self(address=param._array.buffer)._as_ffi()
+
 class _Pointer(_CData):
     __metaclass__ = PointerType
 
@@ -48,6 +56,9 @@
     def setcontents(self, value):
         self._array = self._ffiarray.fromaddress(value._array.buffer, 1)
 
+    def _as_ffi(self):
+        return CArgObject('P', self._array, type(self))
+
     def __getitem__(self, item):
         return self._array[item]
 

Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py	Fri Jan 11 15:50:11 2008
@@ -3,6 +3,7 @@
 SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv"
 
 from _ctypes.basics import _CData
+from _ctypes.param import CArgObject
 
 class NULL(object):
     pass
@@ -54,22 +55,22 @@
                     self._array[0] = value
         dct['__init__'] = __init__
         result = type.__new__(self, name, bases, dct)
+        result._ffiletter = tp
         result._ffiarray = ffiarray
-        result._ffiletter = result._type_
         return result
 
     def from_address(self, address):
-        return self(address=address)
+        return self(address=address)        
 
     def __mul__(self, other):
         pass
 
+    def from_param(self, value):
+        return self(value)._as_ffi()
+
 class _SimpleCData(_CData):
     __metaclass__ = SimpleType
     _type_ = 'i'
-    def from_param(cls, *args, **kwargs):
-        pass
-    from_param = classmethod(from_param)
 
     def _getvalue(self):
         return self._array[0]
@@ -78,6 +79,9 @@
         self._array[0] = value
     value = property(_getvalue, _setvalue)
 
+    def _as_ffi(self):        
+        return CArgObject(self._type_, self.value, type(self))
+
     def __repr__(self):
         return "%s(%s)" % (type(self).__name__, self.value)
 
@@ -91,4 +95,5 @@
     from ctypes import pointer
     if not isinstance(cdata, _SimpleCData):
         raise TypeError("expected CData instance")
-    return pointer(cdata)
+    return pointer(cdata)._as_ffi()
+



More information about the Pypy-commit mailing list