logo       

Re: [PATCH] assortment of problems: msg#00145

programming.swig

Subject: Re: [PATCH] assortment of problems

Steve Fink wrote:

I have been having a series of problems when trying to wrap a couple of templatized C++ classes with Perl. I have finally beaten SWIG into submission with a set of patches, all of one of which are attached to this message.

The first patch, which is not attached because it is large, is John Lenz's type system patch at <http://www.cs.wisc.edu/~lenz/swig.html>. I modified it very slightly, however -- both my C++ library and Perl were using the DEBUG macro, and Lenz's patch added yet another use, so I edited the patch to use SWIG_DEBUG instead. I used this patch because it sounded like it might fix my problems. It didn't, but it still seems like a nice improvement. In fact, I think there's a pretty good chance that it ended up providing a large piece of the solution, but I haven't tried going back and applying all my other patches without it in order to find out.

The second patch (SWIG-1.3.21-warnings.diff) just removes a bunch of warnings about incomplete initializers. The problem is present with or without Lenz's patch, but this patch will only apply on top of his stuff since it changes what gets initialized, while still initializing stuff in the same way.

The third patch (SWIG-1.3.21-debug.diff) adds a -debug flag to SWIG to turn on template debugging (it sets the global template_debug variable). It doesn't do it in a pretty way, but I didn't really care.

The fourth patch (SWIG-1.3.21-qual.diff) makes SWIG look for template name matches both without any namespace qualification (as in swig1.3.21) and with it. I had code like:

namespace std {
template<class T, typename A> class vector<T,A>...
%define specialize_std_vector(T)
template<typename A> class vector<T,A>...
%enddef
}
.
.
.
%template(MyFloatVec) std::vector<float, MyAllocator<float> >;

That compares 'vector' with 'std::vector' and fails. If I instead say 'std::vector' within the 'namespace std' section, it fails because... I forget, and left my notes at home. But it doesn't work, and saying namespace std { std::vector } just seems redundant anyway.

The fifth patch (SWIG-1.3.21-perlshadow.diff) adds a SWIG_FindType routine that searches through all swig_type_info*'s and calls a user-provided function on them, returning the first one that returns true. Then I use that in the perl*.swg files to lookup swig_type_info's for shadow class names (which are stored in ->clientdata). This is because I couldn't figure out any way of wrapping up a C++ object as a Perl shadow class SV from within C++. I could use QueryType and NewPointerObj to wrap things up as the underlying types, but then they would have no association with the shadow type. This patch requires Lenz's patch because the way you iterate through all swig_type_info*'s is different. I really should break this patch up into two patches, one of which just provides SWIG_FindType and has nothing to do with Perl, and then the Perl-specific stuff. But given my fuzzy understanding of the SWIG internals, I'm guessing it's more likely that these patches won't make any sense to people who actually know what's going on, so I'd rather not go to the effort. (But I'd be interested if someone could clean up my use of the various layers of SWIG_XXX and SWIG_Perl_XXX and SWIGIMPORT() and SWIGRUNTIME() and ...?)

I am also attaching the .spec file I use to generate my SWIG RPM, since it includes these patches and also has some changes to properly build outside of the system RPM area. (The provided .spec file leaks various files into system directories.)

Finally, I should note that some of this will not apply to the current CVS, because it has added some weird A vs B|C|D type equivalency searching that collides with Lenz's patch. I didn't bother to look at why it's needed, because everything is finally working for me (as far as I can tell so far!).


The "B|C" type equivalence is there to solve several problems with templates + typedefs + namespaces,
in the example

namespace A {
struct OpaqueStruct;
typedef struct OpaqueStruct OpaqueType;
typedef std::vector<OpaqueType> OpaqueVectorType;

void FillVector(OpaqueVectorType);
}

it generates

"_p_A__OpaqueVectorType" => "std::vector<A::OpaqueStruct > *|A::OpaqueVectorType *"


ie, it keeps the equivalence between "A::OpaqueVectorType" and the fully resolved
primitive type "std::vector<A::OpaqueStruct >".

Probably it will also fix some of the problems you are addressing with your patches.


Marcelo

Yes, I know I ought to be filing bugs for all of these things, but I've probably spent far too much time already struggling with this stuff. I'll try to at least put these patches into the tracker.



_______________________________________________
Swig maillist - Swig@xxxxxxxxxxxxxxx
http://mailman.cs.uchicago.edu/mailman/listinfo/swig



<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise