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