|
From: Vadim Z. <vz...@ze...> - 2013-08-31 23:57:13
|
Hello,
I'm trying to make the following work:
----------------------------------------------------------------------------
%module ov
%inline %{
template <typename T>
struct OptionalValue {
OptionalValue();
OptionalValue(const T& value);
bool IsValid() const;
const T& Get() const;
};
%}
%define DEFINE_OPTIONAL(T)
%template(Optional ## T) OptionalValue< T >;
%typemap(cstype) OptionalValue< T >, const OptionalValue< T >& "$typemap(cstype, T)?"
%typemap(cstype, out="$typemap(cstype, T)?") OptionalValue< T >* "ref $typemap(cstype, T)?"
%enddef
DEFINE_OPTIONAL(double)
%inline %{
struct S {
OptionalValue<double> od;
};
%}
----------------------------------------------------------------------------
The idea being that I want to allow handling my OptionalValue<T> objects as
"T?" (a.k.a. Nullable<T>) in C# for the convenience of the code using it.
There are plenty missing typemaps here, of course, but I already have a
big problem: while the "$typemap(...)" expressions in the main typemap
definition are getting expanded in the output, the value of "out" parameter
appears as is, i.e. just as "$typemap(cstype, double)?" directly in the
output C# code.
I've tried debugging why does it happen and, after spending an hour or so
(I wish I knew how could I find stuff like this faster in SWIG code base),
found that it was due to replace_embedded_typemap() only being called
inside Swig_typemap_lookup_impl() which is not used for the "out" value
which is used directly by the code in proxyClassFunctionHandler() in
csharp.cxx:
if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) {
// Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type
SwigType *covariant = Getattr(n, "covariant");
String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
if (cstypeout)
tm = cstypeout;
...
}
So I had some hope that I could just call replace_embedded_typemap() from
here (after making it public) and solve my problem. Unfortunately, it's not
as simple as this. First of all, replace_embedded_typemap() expects
"$TYPEMAP()" instead of "$typemap()", which is, according to the comments
in the code, a hack, but I don't know what is this hack for and why is it
needed. Second, even if I use $TYPEMAP() it still doesn't work, apparently
because I don't pass the correct ParmList to it. But I have no idea how to
create a correct one nor even whether I'm trying to do it in the right way,
e.g. perhaps it's the code in Swig_typemap_lookup_impl() itself that should
be doing this expansion? And if so, should it use typemap_replace_vars()
for this?
I'd really appreciate some advice about how to proceed here because I'm
feeling hopefully lost.
TIA!
VZ
|