« Return to Thread: C++ loses reference to Java Director instance

Re: C++ loses reference to Java Director instance

by wsfulton :: Rate this Message:

Reply to Author | View in Thread

Costas wrote:

>
> I am having a weird issue with SWIG-wrapped classes in Java: it looks
> like my SWIGed C++ code is losing a reference to a Java Director
> instance if called out of the original scope.  Here's my structure in C++:
>
> class Factory : public BaseFactory<Car> {
>     Factory::Factory(Getter& getter)
>     : BaseFactory<Car>(getter)
>     {};
>          
>     ...
> };
>
> template typename<T>
> class BaseFactory
> {
>    BaseFactory(Getter& getter)
>    : _getter(getter.clone())
>    {};
>  
>    void run()
>    {
>       _getter->doSomething();
>    }
>    ...
>  
>    private Getter* _getter;
> }
>
> Now, Factory, BaseFactory and Getter are all wrapped in SWIG, and Getter
> is a director with a JavaGetter that extends it:
>
> public class JavaGetter extends Getter
> {
>    public JavaGetter(JavaGetter other)
>    {
>    ...
>    }
>  
>    public JavaGetter clone()
>    {
>       return new JavaGetter(this);
>    }
> }
>
> Now here's where things get nutty.  I have a function like this:
>
>    JavaGetter g = new JavaGetter();
>    Factory factory = new Factory(g);
>  
>    doStuff(factory);
>    factory.run();
>  
> If I call factory.run() within the above scope everything works fine.  
> The SWIGed Factory instance calls the JavaGetter instance from C++ and
> everything's great.  However, if I pass 'factory' to another function in
> another scope (say doStuff()), it looks like the underlying C++ Factory
> instance loses the reference to JavaGetter: within that scope, if I
> examine Factory in C++, the reference is no longer valid, and calling
> factory.run() blows up the JVM.
>
> I am guessing there's an interaction with clone() here somewhere: if I
> take out clone() from the copy constructor of BaseFactory() everything
> works fine in Java, regardless of scope (it blows up the C++ client
> though which is not an option).
>
> Is the temporary JavaGetter() called in the BaseFactory constructor not
> in scope and thus gone outside the above function? if so, is there a way
> for me to pin it down in the BaseFactory instance and then release it later?
>
>
Can you put together a complete standalone testcase that compiles and I
might take a look. Modify what I got below to show the problem.

%module(directors="1") example

%feature("director");

%inline %{

class Car{};
struct Getter{
   Getter() {}
   Getter(const Getter& other) {}
   virtual ~Getter() {}
   virtual Getter* clone() { return new Getter(*this); }
   void doSomething() {}
};

template <typename T>
class BaseFactory
{
public:
    BaseFactory(Getter& getter)
    : _getter(getter.clone())
    {}

    void run()
    {
       _getter->doSomething();
    }

private:
    Getter* _getter;
};
%}

%template(BaseFactoryCar) BaseFactory<Car>;

%inline %{

class Factory : public BaseFactory<Car> {
public:
     Factory(Getter& getter)
     : BaseFactory<Car>(getter)
     {}
};

%}

Java code:

/*public*/ class JavaGetter extends Getter
{
    public JavaGetter()
    {
      super();
    }
    public JavaGetter(JavaGetter other)
    {
      super(other);
//   ...
    }

    public JavaGetter clone()
    {
       return new JavaGetter(this);
    }
}

   public static void main(String argv[])
   {
     JavaGetter g = new JavaGetter();
     Factory factory = new Factory(g);

//    doStuff(factory);
     factory.run();
   }

William

------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user

 « Return to Thread: C++ loses reference to Java Director instance