|
|
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
|
|