[pypy-commit] pypy reflex-support: allow python str to pass through std::string and const std::string&
wlav
noreply at buildbot.pypy.org
Sat Feb 18 06:36:05 CET 2012
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r52597:a11f7dc9ad01
Date: 2012-02-17 16:23 -0800
http://bitbucket.org/pypy/pypy/changeset/a11f7dc9ad01/
Log: allow python str to pass through std::string and const std::string&
diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py
--- a/pypy/module/cppyy/capi/__init__.py
+++ b/pypy/module/cppyy/capi/__init__.py
@@ -244,3 +244,18 @@
voidp = rffi.cast(rffi.VOIDP, charp)
c_free(voidp)
return string
+
+c_charp2stdstring = rffi.llexternal(
+ "cppyy_charp2stdstring",
+ [rffi.CCHARP], rffi.VOIDP,
+ compilation_info=backend.eci)
+
+c_stdstring2stdstring = rffi.llexternal(
+ "cppyy_stdstring2stdstring",
+ [rffi.VOIDP], rffi.VOIDP,
+ compilation_info=backend.eci)
+
+c_free_stdstring = rffi.llexternal(
+ "cppyy_free_stdstring",
+ [rffi.VOIDP], lltype.Void,
+ compilation_info=backend.eci)
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
@@ -1,5 +1,7 @@
import sys
+from pypy.interpreter.error import OperationError
+
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.rlib.rarithmetic import r_singlefloat
from pypy.rlib import jit, libffi, clibffi, rfloat
@@ -532,6 +534,36 @@
return interp_cppyy.new_instance(space, w_type, self.cpptype, address, False)
+class StdStringConverter(InstanceConverter):
+ _immutable_ = True
+
+ def __init__(self, space, extra):
+ from pypy.module.cppyy import interp_cppyy
+ cpptype = interp_cppyy.type_byname(space, "std::string")
+ InstanceConverter.__init__(self, space, cpptype, "std::string")
+
+ def _unwrap_object(self, space, w_obj):
+ try:
+ charp = rffi.str2charp(space.str_w(w_obj))
+ arg = capi.c_charp2stdstring(charp)
+ rffi.free_charp(charp)
+ return arg
+ except OperationError:
+ arg = InstanceConverter._unwrap_object(self, space, w_obj)
+ return capi.c_stdstring2stdstring(arg)
+
+ def free_argument(self, arg):
+ capi.c_free_stdstring(rffi.cast(rffi.VOIDPP, arg)[0])
+
+class StdStringRefConverter(InstancePtrConverter):
+ _immutable_ = True
+
+ def __init__(self, space, extra):
+ from pypy.module.cppyy import interp_cppyy
+ cpptype = interp_cppyy.type_byname(space, "std::string")
+ InstancePtrConverter.__init__(self, space, cpptype, "std::string")
+
+
_converters = {} # builtin and custom types
_a_converters = {} # array and ptr versions of above
def get_converter(space, name, default):
@@ -614,6 +646,14 @@
_converters["void**"] = VoidPtrPtrConverter
_converters["void*&"] = VoidPtrRefConverter
+# special cases
+_converters["std::string"] = StdStringConverter
+_converters["std::basic_string<char>"] = StdStringConverter
+_converters["const std::string&"] = StdStringConverter # TODO: shouldn't copy
+_converters["const std::basic_string<char>&"] = StdStringConverter
+_converters["std::string&"] = StdStringRefConverter
+_converters["std::basic_string<char>&"] = StdStringRefConverter
+
# it should be possible to generate these:
_a_converters["short int*"] = ShortPtrConverter
_a_converters["short*"] = _a_converters["short int*"]
diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h
--- a/pypy/module/cppyy/include/capi.h
+++ b/pypy/module/cppyy/include/capi.h
@@ -79,6 +79,10 @@
long long cppyy_strtoll(const char* str);
unsigned long long cppyy_strtuoll(const char* str);
+ void* cppyy_charp2stdstring(const char* str);
+ void* cppyy_stdstring2stdstring(void* ptr);
+ void cppyy_free_stdstring(void* ptr);
+
#ifdef __cplusplus
}
#endif // ifdef __cplusplus
diff --git a/pypy/module/cppyy/src/reflexcwrapper.cxx b/pypy/module/cppyy/src/reflexcwrapper.cxx
--- a/pypy/module/cppyy/src/reflexcwrapper.cxx
+++ b/pypy/module/cppyy/src/reflexcwrapper.cxx
@@ -408,3 +408,16 @@
void cppyy_free(void* ptr) {
free(ptr);
}
+
+void* cppyy_charp2stdstring(const char* str) {
+ return new std::string(str);
+}
+
+void* cppyy_stdstring2stdstring(void* ptr) {
+ return new std::string(*(std::string*)ptr);
+}
+
+void cppyy_free_stdstring(void* ptr) {
+ delete (std::string*)ptr;
+}
+
diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py
--- a/pypy/module/cppyy/test/test_stltypes.py
+++ b/pypy/module/cppyy/test/test_stltypes.py
@@ -153,8 +153,6 @@
c.set_string1(s)
assert c.get_string1() == s
- return
-
c.set_string1("test2")
assert c.get_string1() == "test2"
More information about the pypy-commit
mailing list