Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r46624:f45d20e1976d
Date: 2011-08-18 12:33 -0700
http://bitbucket.org/pypy/pypy/changeset/f45d20e1976d/
Log: void pointer passing and addressof() operator
diff --git a/pypy/module/cppyy/__init__.py b/pypy/module/cppyy/__init__.py
--- a/pypy/module/cppyy/__init__.py
+++ b/pypy/module/cppyy/__init__.py
@@ -8,6 +8,7 @@
'_type_byname' : 'interp_cppyy.type_byname',
'_template_byname' : 'interp_cppyy.template_byname',
'CPPInstance' : 'interp_cppyy.W_CPPInstance',
+ 'addressof' : 'interp_cppyy.addressof',
}
appleveldefs = {
diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -409,6 +409,38 @@
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'
@@ -528,6 +560,7 @@
from pypy.module.cppyy import interp_cppyy
# 1) full, exact match
+ print 'asking for: ',
try:
return _converters[name](space, -1)
except KeyError, k:
@@ -609,3 +642,6 @@
_converters["double[]"] = DoubleArrayConverter
_converters["const char*"] = CStringConverter
_converters["char*"] = CStringConverter
+_converters["void*"] = VoidPtrConverter
+_converters["void**"] = VoidPtrPtrConverter
+_converters["void*&"] = VoidPtrRefConverter
diff --git a/pypy/module/cppyy/interp_cppyy.py
b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -68,6 +68,12 @@
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"]
diff --git a/pypy/module/cppyy/test/advancedcpp.h
b/pypy/module/cppyy/test/advancedcpp.h
--- a/pypy/module/cppyy/test/advancedcpp.h
+++ b/pypy/module/cppyy/test/advancedcpp.h
@@ -277,3 +277,20 @@
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;
+ }
+};
diff --git a/pypy/module/cppyy/test/advancedcpp.xml
b/pypy/module/cppyy/test/advancedcpp.xml
--- a/pypy/module/cppyy/test/advancedcpp.xml
+++ b/pypy/module/cppyy/test/advancedcpp.xml
@@ -27,4 +27,6 @@
<class name="some_abstract_class" />
<class name="some_concrete_class" />
+ <class name="pointer_pass" />
+
</lcgdict>
diff --git a/pypy/module/cppyy/test/fragile.h b/pypy/module/cppyy/test/fragile.h
--- a/pypy/module/cppyy/test/fragile.h
+++ b/pypy/module/cppyy/test/fragile.h
@@ -39,4 +39,11 @@
A** m_pp_a;
};
+class F {
+public:
+ F() : m_int(0) {}
+ virtual int check() { return (int)'F'; }
+ int m_int;
+};
+
} // namespace fragile
diff --git a/pypy/module/cppyy/test/test_advancedcpp.py
b/pypy/module/cppyy/test/test_advancedcpp.py
--- a/pypy/module/cppyy/test/test_advancedcpp.py
+++ b/pypy/module/cppyy/test/test_advancedcpp.py
@@ -321,3 +321,17 @@
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)
diff --git a/pypy/module/cppyy/test/test_fragile.py
b/pypy/module/cppyy/test/test_fragile.py
--- a/pypy/module/cppyy/test/test_fragile.py
+++ b/pypy/module/cppyy/test/test_fragile.py
@@ -86,3 +86,23 @@
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)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit