C++ loses reference to Java Director instance

View: New views
2 Messages — Rating Filter:   Alert me  

C++ loses reference to Java Director instance

by Costas-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

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?

Costas


------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user

Re: C++ loses reference to Java Director instance

by wsfulton :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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