Jason Roelofs wrote:
> 
> 
> SWIG does not handle nested classes, a *serious* defect to what I'm 
> trying to do. 

Which is partially not true.  SWIG supports nested classes just fine but 
you need to provide more glue code to expose the class as the swig 
*parser* will not automatically parse them for you.  The amount of code 
you need to write is probably less than the equivalent of boost python.

Here's a simple dummy example.

----

%module nested


%inline {

   class A
   {
   public:
     A()  {}
     ~A() {}

     class B
     {
     public:
       B()  {}
       ~B() {}
     };

   };

}

// We declare a typedef so that A__B will mean something to the compiler
%{
   typedef A::B A__B;
%}

// the glue code--- we copy the B definition here and call it A__B
class A__B
{
public:
   A__B()  {}
   ~A__B() {}
};

%init {
   // we define a constant inside A so we can invoke A::B.new()
   rb_define_const(cA.klass, "B", cA__B.klass );
  }



If the nested class is declared as protected, afaik, neither swig nor 
boost python will be able to do much with it.


I've looked into helping add this feature, but the amount
> of work required makes it more feasible to build a better, Ruby-specific 
> wrapper system.
> 
> And comparing Boost.Python to SWIG really doesn't make sense. You need 
> to compare Boost.Python with Py++ to SWIG.

Same thing.

> 
> I'm going to post this to Ruby-core as well to see if I can glean any 
> insight from those who know the innards of Ruby.
> 
> 
>   // Actual function call, this causes segfault

Sure.  You are passing the address of the function object, not the 
function.  You might get what you want if you use f1.target(), which 
returns a Functor* (ie. the address of the actual function or functor).

But again as I already mentioned, that may still prove not portable, 
unless you modify boost::function, as the calling convention used in a 
functor by default is probably not cdecl.  For more info, see:
http://en.wikipedia.org/wiki/Stdcall

Your best bet is to avoid using a functor or call the functor through a 
C function, like:

extern "C"
VALUE call_functor( VALUE self, VALUE args )
{
	functor* f = (functor*) args[0];
	return f->operator()(self, args[1]);
}

and always pass the functor (cast to VALUE) as the first argument to the 
function.  That's slightly slower, but it is surely portable.



-- 
Gonzalo Garramu˝´
ggarra / advancedsl.com.ar

AMD4400 - ASUS48N-E
GeForce7300GT
Xubuntu Gutsy