From: William S F. <ws...@fu...> - 2014-01-21 07:47:43
|
On 21/01/14 01:32, Vadim Zeitlin wrote: > Hello William, > > Unfortunately fixing the shared_ptr/naturalvar problem discussed > previously wasn't enough to make my code work with SWIG 3.0.0 (i.e. latest > Git). I have another template class which requires the use of naturalvar > (see http://thread.gmane.org/gmane.comp.programming.swig.devel/22654 for > the explanation why) and which is broken now. My test case is > > % cat -n ov.i > 1 %module ov > 2 > 3 %inline %{ > 4 template <typename T> > 5 class OptionalValue > 6 { > 7 public: > 8 OptionalValue(); > 9 OptionalValue(const T& value); > 10 OptionalValue(const OptionalValue& other); > 11 OptionalValue& operator=(const OptionalValue& other); > 12 > 13 bool IsValid() const; > 14 > 15 const T& Get() const; > 16 }; > 17 %} > 18 > 19 %define DEFINE_OPTIONAL(T) > 20 %template(Optional ## T) OptionalValue< T >; > 21 %naturalvar OptionalValue< T >; > 22 %typemap(cstype) const OptionalValue< T >& "$typemap(cstype, T)?" > 23 %typemap(csin) const OptionalValue< T >& "$csclassname.getCPtr(opt$csinput)" > 24 > 25 %typemap(csvarin, excode=SWIGEXCODE2) const OptionalValue< T >& %{ > 26 set { > 27 OptionalValue ## T optvalue = value.HasValue ? new OptionalValue ## T(value) : new OptionalValue(); > 28 $imcall;$excode > 29 }%} > 30 %typemap(csvarout, excode=SWIGEXCODE2) const OptionalValue< T >& %{ > 31 get { > 32 Optional ## T ret = new Optional ## T($imcall, $owner);$excode > 33 return ret.IsValid() ? ret.Get() : null; > 34 }%} > 35 %enddef > 36 > 37 DEFINE_OPTIONAL(double) > 38 > 39 %inline %{ > 40 struct S { > 41 OptionalValue<double> od; > 42 }; > 43 %} > % swig -csharp -c++ -o wrap_ov_csharp.cpp ov.i > > > Examining the generated S.cs it's immediately clear that the typemaps are > not applied (this can also be seen by using -debug-tmused). And the reason > for this is that naturalvar is ignored and SWIG looks for the pointer > typemaps when wrapping "od" field, not the reference ones. > There are no more temporary copied nodes with the current %naturalvar implementation, so you can use "swig -debug-module 1" to look at what features are attached to OptionalValue<double>. You'll notice that "feature:naturalvar" is missing. What you intended it to have is: +++ class ---------------------------------------- | name - "OptionalValue<(double)>" | sym:name - "Optionaldouble" ... | feature:naturalvar - "1" ... If you swap lines 20 and 21 to %naturalvar OptionalValue< T >; %template(Optional ## T) OptionalValue< T >; then "feature:naturalvar" does attach to OptionalValue<double>. This is simply because of the way features work... The %feature needs to be defined before the type is defined in order for it to be attached in much the same way that a C++ type needs to be defined before it can be used. Alternatively, a more general approach can be used to get the feature to attach to the template and hence instantiations with all types, not just the instantiation using double. Use this before SWIG parses template<typename T> OptionalValue in line 4 %naturalvar ::OptionalValue; Then it will attach to the template: +++ template ---------------------------------------- | templatetype - "class" | name - "OptionalValue" | sym:name - "OptionalValue" | feature:naturalvar - "1" ... in addition to the OptionalValue<double> class (instantiation of the template). > To summarize, e186d21 breaks my existing code (and probably not only mine) > and there doesn't seem to be any work around. So IMNSHO this is something > that should be fixed, even if by (partially) reverting this commit before > 3.0. > This is a concern, but I still mostly think that the fix is the correct approach and your current problem is because your code is wrong. William |