1. Bruno Gola
  2. pypy

Commits

wlav  committed f45d20e

void pointer passing and addressof() operator

  • Participants
  • Parent commits 249d77d
  • Branches reflex-support

Comments (0)

Files changed (8)

File pypy/module/cppyy/__init__.py

View file
         '_type_byname'           : 'interp_cppyy.type_byname',
         '_template_byname'       : 'interp_cppyy.template_byname',
         'CPPInstance'            : 'interp_cppyy.W_CPPInstance',
+        'addressof'              : 'interp_cppyy.addressof',
     }
 
     appleveldefs = {

File pypy/module/cppyy/converter.py

View file
         lltype.free(rffi.cast(rffi.CCHARPP, arg)[0], flavor='raw')
 
 
+class VoidPtrConverter(TypeConverter):
+    _immutable_ = True
+
+    def convert_argument(self, space, w_obj, address):
+        x = rffi.cast(rffi.VOIDPP, address)
+        obj_address = get_rawobject(space, w_obj)
+        x[0] = obj_address
+        typecode = _direct_ptradd(address, capi.c_function_arg_typeoffset())
+        typecode[0] = 'a'
+
+    def convert_argument_libffi(self, space, w_obj, argchain):
+        argchain.arg(get_rawobject(space, w_obj))
+
+
+class VoidPtrPtrConverter(TypeConverter):
+    _immutable_ = True
+
+    def convert_argument(self, space, w_obj, address):
+        x = rffi.cast(rffi.VOIDPP, address)
+        obj_address = get_rawobject(space, w_obj)
+        x[0] = obj_address
+
+
+class VoidPtrRefConverter(TypeConverter):
+    _immutable_ = True
+
+    def convert_argument(self, space, w_obj, address):
+        x = rffi.cast(rffi.VOIDPP, address)
+        obj_address = get_rawobject(space, w_obj)
+        x[0] = obj_address
+
+
 class ShortArrayConverter(ArrayTypeConverterMixin, TypeConverter):
     _immutable_ = True
     typecode = 'h'
     from pypy.module.cppyy import interp_cppyy
 
     #   1) full, exact match
+    print 'asking for: ', 
     try:
         return _converters[name](space, -1)
     except KeyError, k:
 _converters["double[]"]                 = DoubleArrayConverter
 _converters["const char*"]              = CStringConverter
 _converters["char*"]                    = CStringConverter
+_converters["void*"]                    = VoidPtrConverter
+_converters["void**"]                   = VoidPtrPtrConverter
+_converters["void*&"]                   = VoidPtrRefConverter

File pypy/module/cppyy/interp_cppyy.py

View file
     return None
 template_byname.unwrap_spec = [ObjSpace, str]
 
+def addressof(space, w_cppinstance):
+     cppinstance = space.interp_w(W_CPPInstance, w_cppinstance, can_be_None=False)
+     address = rffi.cast(rffi.LONG, cppinstance.rawobject)
+     return space.wrap(address)
+addressof.unwrap_spec = [ObjSpace, W_Root]
+
 
 class W_CPPLibrary(Wrappable):
     _immutable_fields_ = ["cdll"]

File pypy/module/cppyy/test/advancedcpp.h

View file
 
    some_data m_data;
 };
+
+
+//===========================================================================
+class pointer_pass {             // for testing passing of void*'s
+public:
+    long gime_address_ptr(void* obj) {
+        return (long)obj;
+    }
+
+    long gime_address_ptr_ptr(void** obj) {
+        return (long)*((long**)obj);
+    }
+
+    long gime_address_ptr_ref(void*& obj) {
+        return (long)obj;
+    }
+};

File pypy/module/cppyy/test/advancedcpp.xml

View file
   <class name="some_abstract_class" />
   <class name="some_concrete_class" />
 
+  <class name="pointer_pass" />
+
 </lcgdict>

File pypy/module/cppyy/test/fragile.h

View file
     A** m_pp_a;
 };
 
+class F {
+public:
+    F() : m_int(0) {}
+    virtual int check() { return (int)'F'; }
+    int m_int;
+};
+
 } // namespace fragile

File pypy/module/cppyy/test/test_advancedcpp.py

View file
         assert gbl.get_c(d) == 33
         assert gbl.get_d(d) == 44
         d.destruct()
+
+    def test08_void_pointer_passing( self ):
+        """Test passing of variants of void pointer arguments"""
+
+        import cppyy
+        pointer_pass        = cppyy.gbl.pointer_pass
+        some_concrete_class = cppyy.gbl.some_concrete_class
+
+        pp = pointer_pass()
+        o = some_concrete_class()
+
+        assert cppyy.addressof(o) == pp.gime_address_ptr(o)
+        assert cppyy.addressof(o) == pp.gime_address_ptr_ptr(o)
+        assert cppyy.addressof(o) == pp.gime_address_ptr_ref(o)

File pypy/module/cppyy/test/test_fragile.py

View file
         e = fragile.E()
         raises(TypeError, e.overload, None)
         raises(NotImplementedError, getattr, e, 'm_pp_no_such')
+
+    def test05_wrong_arg_addressof(self):
+        """Test addressof() error reporting"""
+
+        import cppyy
+
+        assert cppyy.gbl.fragile == cppyy.gbl.fragile
+        fragile = cppyy.gbl.fragile
+
+        assert fragile.F == fragile.F
+        assert fragile.F().check() == ord('F')
+
+        f = fragile.F()
+        o = object()
+
+        cppyy.addressof(f)
+        raises(TypeError, cppyy.addressof, o)
+        raises(TypeError, cppyy.addressof, 0)
+        raises(TypeError, cppyy.addressof, 1)
+        raises(TypeError, cppyy.addressof, None)