Add cxx{in,out}type typemaps and use them for std::string
This makes using returning strings much simpler to use from C++ code as the returned pointers don't have to be deleted manually -- although, of course, this does require an extra allocation and copy and so should be avoided for the very long strings. Add a new runtime test showing how simple and convenient it is to use the functions working with string using the C++ wrappers now.
This commit is contained in:
parent
8b871b10fe
commit
fd11a591a3
5 changed files with 135 additions and 30 deletions
|
|
@ -611,35 +611,49 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
for (; p; p = nextSibling(p)) {
|
||||
// Static variables use fully qualified names, so we can't just use the name directly.
|
||||
scoped_dohptr name_ptr;
|
||||
String* name = Getattr(p, "name");
|
||||
if (!name) {
|
||||
// Parameters can also not have any names at all, in which case we use auto-generated one.
|
||||
name = Getattr(p, "lname");
|
||||
} else if (Strstr(name, "::")) {
|
||||
name_ptr = Swig_scopename_last(name);
|
||||
name = name_ptr.get();
|
||||
if (p) {
|
||||
// We want to use readable parameter names in our wrappers instead of the autogenerated arg$N if possible, so do it, and do it before calling
|
||||
// Swig_typemap_attach_parms(), as this uses the parameter names for typemap expansion.
|
||||
for (Parm* p2 = p; p2; p2 = nextSibling(p2)) {
|
||||
String* name = Getattr(p, "name");
|
||||
if (!name) {
|
||||
// Can't do anything for unnamed parameters.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Static variables use fully qualified names, so we need to strip the scope from them.
|
||||
scoped_dohptr name_ptr;
|
||||
if (Strstr(name, "::")) {
|
||||
name_ptr = Swig_scopename_last(name);
|
||||
name = name_ptr.get();
|
||||
}
|
||||
|
||||
Setattr(p, "lname", name);
|
||||
}
|
||||
|
||||
const type_desc ptype_desc = lookup_cxx_parm_type(n, p);
|
||||
if (!ptype_desc.type()) {
|
||||
Swig_warning(WARN_C_TYPEMAP_CTYPE_UNDEF, Getfile(p), Getline(p),
|
||||
"No ctype typemap defined for the parameter \"%s\" of %s\n",
|
||||
name,
|
||||
Getattr(n, "sym:name")
|
||||
);
|
||||
return;
|
||||
Swig_typemap_attach_parms("cxxin", p, NULL);
|
||||
|
||||
for (; p; p = nextSibling(p)) {
|
||||
String* const name = Getattr(p, "lname");
|
||||
|
||||
const cxx_ptype_desc ptype_desc = lookup_cxx_parm_type(n, p);
|
||||
if (!ptype_desc.type()) {
|
||||
Swig_warning(WARN_C_TYPEMAP_CTYPE_UNDEF, Getfile(p), Getline(p),
|
||||
"No ctype typemap defined for the parameter \"%s\" of %s\n",
|
||||
name,
|
||||
Getattr(n, "sym:name")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Len(parms_cxx))
|
||||
Append(parms_cxx, ", ");
|
||||
Printv(parms_cxx, ptype_desc.type(), " ", name, NIL);
|
||||
|
||||
if (Len(parms_call))
|
||||
Append(parms_call, ", ");
|
||||
Append(parms_call, ptype_desc.get_param_code(name));
|
||||
}
|
||||
|
||||
if (Len(parms_cxx))
|
||||
Append(parms_cxx, ", ");
|
||||
Printv(parms_cxx, ptype_desc.type(), " ", name, NIL);
|
||||
|
||||
if (Len(parms_call))
|
||||
Append(parms_call, ", ");
|
||||
Append(parms_call, ptype_desc.get_param_code(name));
|
||||
}
|
||||
|
||||
// Avoid checking for exceptions unnecessarily. Note that this is more than an optimization: we'd get into infinite recursion if we checked for exceptions
|
||||
|
|
@ -1006,6 +1020,9 @@ private:
|
|||
// The logic here is somewhat messy because we use the same "$resolved_type*" typemap for pointers/references to both enums and classes, but we actually
|
||||
// need to do quite different things for them. It could probably be simplified by changing the typemaps to be distinct, but this would require also updating
|
||||
// the code for C wrappers generation in substituteResolvedTypeSpecialVariable().
|
||||
//
|
||||
// An even better idea might be to try to define this using cxx{in,out} typemaps for the various types and let the generic SWIG machinery do all the
|
||||
// matching instead of doing it in the code here.
|
||||
scoped_dohptr resolved_type(SwigType_typedef_resolve_all(type));
|
||||
scoped_dohptr base_resolved_type(SwigType_base(resolved_type));
|
||||
|
||||
|
|
@ -1182,11 +1199,23 @@ private:
|
|||
// Ensure our own replaceSpecialVariables() is used for $typemap() expansion.
|
||||
temp_ptr_setter<cxx_ptype_desc*> set(&ptype_desc_, &ptype_desc);
|
||||
|
||||
if (String* type = Swig_typemap_lookup("ctype", p, "", NULL)) {
|
||||
bool use_cxxin = true;
|
||||
String* type = Swig_typemap_lookup("cxxintype", p, "", NULL);
|
||||
if (!type) {
|
||||
use_cxxin = false;
|
||||
type = Swig_typemap_lookup("ctype", p, "", NULL);
|
||||
}
|
||||
|
||||
if (type) {
|
||||
ptype_desc.set_type(type);
|
||||
do_resolve_type(n, Getattr(p, "type"), ptype_desc.type(), &ptype_desc, NULL);
|
||||
}
|
||||
|
||||
if (use_cxxin) {
|
||||
if (String* in_tm = Getattr(p, "tmap:cxxin"))
|
||||
ptype_desc.apply_in_typemap(Copy(in_tm));
|
||||
}
|
||||
|
||||
return ptype_desc;
|
||||
}
|
||||
|
||||
|
|
@ -1194,13 +1223,24 @@ private:
|
|||
// As above, ensure our replaceSpecialVariables() is used.
|
||||
temp_ptr_setter<cxx_rtype_desc*> set(&rtype_desc_, &rtype_desc);
|
||||
|
||||
String* type = Swig_typemap_lookup("ctype", n, "", NULL);
|
||||
bool use_cxxout = true;
|
||||
String* type(Swig_typemap_lookup("cxxouttype", n, "", NULL));
|
||||
if (!type) {
|
||||
use_cxxout = false;
|
||||
type = Swig_typemap_lookup("ctype", n, "", NULL);
|
||||
}
|
||||
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
rtype_desc.set_type(type);
|
||||
do_resolve_type(n, Getattr(n, "type"), rtype_desc.type(), NULL, &rtype_desc);
|
||||
|
||||
if (use_cxxout) {
|
||||
if (String* out_tm = Swig_typemap_lookup("cxxout", n, "", NULL))
|
||||
rtype_desc.apply_out_typemap(out_tm);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue