Re: %factory and templates
William S Fulton <[email protected]>
| Newsgroups | gmane.comp.programming.swig |
|---|---|
| Message-ID | <CANGqftBHKznwq-69Si=vr6un7ZzGxHbG-tG5Zd+xaLpTsd55MA@mail.gmail.com> |
On Sun, 18 Oct 2020 at 00:58, <[email protected]> wrote: > *From:* kris.f.thielemans > *Sent:* 10 October 2020 00:23 > > > > *From:* William S Fulton <[email protected]> > *Sent:* 09 October 2020 19:03 > > > > On Fri, 9 Oct 2020 at 16:42, <kris.f.thielemans > wrote: > > Hi > > > > We are trying to use %factory (see > https://github.com/swig/swig/blob/master/Lib/typemaps/factory.swg) to let > SWIG do automatic downcasting to the actual types, as opposed to just > returning the base class. However, at present it isn’t working for us. Our > hunch is that this is due to templates and typemaps (which I don’t > understand well enough). We haven’t boiled it down to a simple example yet, > but I thought maybe would know the answer straight-away 😊 > > > > We have a hierarchy like this (apologies for long names, but I kept the > ones in our actual code) > > > > stir::GeneralisedPrior<TargetT > > > stir::QuadraticPrior<elemT> : public > stir::GeneralisedPrior<DiscretisedDensity<3,elemT> > > > stir::RelativeDifferencePrior<elemT> : public > stir::GeneralisedPrior<DiscretisedDensity<3,elemT> > > > > > (cutting out some intermediate classes) > > > > We then have some other templated class that has a member > > > > stir::GeneralisedPrior<TargetT > > *GeneralisedObjectiveFunction<TargetT>::get_prior_ptr() > > > > So, in our SWIG interface file we say > > > > %newobject *::get_prior_ptr; > > %factory(stir::GeneralisedPrior > *stir::GeneralisedObjectiveFunction::get_prior_ptr, stir::QuadraticPrior, > stir::PLSPrior, stir::RelativeDifferencePrior); > > > > i.e. without any template stuff at all, but it seems that the typemap > generated by %factory isn’t picked up. > > > > Anyone any suggestions? > > > > > > > > You need to instantiate your templates with %template if you aren't > already. > > > > William > > > > Thanks William, > > > > Sorry to have posted incomplete code, but it is rather long due to the > somewhat complicated hierarchy. We can try to make a reduced example. The > %templates are there. Indeed, all the classes are callable from Python. It > is just that the “factory” (get_prior_ptr) still returns a base object (GeneralisedPrior), > as opposed to one of the leaf classes (QuadraticPrior etc). > > > > Relevant bits of our interface file are: > > - %newobject, %factor, %include at > https://github.com/UCL/STIR/blob/9c72b9ee8d584f4fd5729f496b7927fec8f55e4e/src/swig/stir.i#L1582-L1595 > > - %template stuff at > https://github.com/UCL/STIR/blob/9c72b9ee8d584f4fd5729f496b7927fec8f55e4e/src/swig/stir.i#L1634-L1650 > > > > I’m not sure how to debug the typemap question but will have a look at the > debug switches of SWIG, unless there are any easier suggestions. > > > > > > After including factory.i (sorry!), it does work if I add *complete > template specifications*, as in > > > > %factory(stir::GeneralisedPrior<TargetT> > *stir::GeneralisedObjectiveFunction< TargetT >::get_prior_ptr, > > stir::QuadraticPrior<elemT>, > > stir::PLSPrior<elemT>, > > stir::RelativeDifferencePrior<elemT>); > > > > where I have a %define for TargetT and elemT. I suppose I would have to > repeat this for every instantiation that I want. (Indeed, it seems unlikely > that SWIG can figure this out if I don’t specify the template arguments, as > it wouldn’t know what to insert in the wrapper code). > > > > Great! > > > > However, now I stumble on another problem. In our actual code, the derived > class can itself be a *template with 2 or more arguments*, e.g. in a > simple example > > > > %factory(Base* Base::create, mytemplate<int,int>); > > > > When running SWIG, I get an error > > > > Error: Bad $descriptor() macro. > > > > I presume this is because of the comma. So I tried William’s trick he told > me once about: use %arg(). As in > > > > %factory(Base* Base::create, %arg(mytemplate<int,int>)); > > > > But that didn’t help either. Conceivably this could be because the factory > macro would itself have to use %arg somehow, e.g. here > > > https://github.com/swig/swig/blob/b6c2438d7d7aac5711376a106a156200b7ff1056/Lib/typemaps/factory.swg#L84 > > but I have no idea really. > Look at the preprocessor output after the macro expansions using swig -E. Quite possibly the %factory macros need some extra %arg usage. There is far too much weird macro hackery in %factory, I would just write it out long hand if it doesn't work or put aside some considerable time to debug these non-standard macros! William William _______________________________________________ Swig-user mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/swig-user