From: Stefan R. <sw...@mi...> - 2012-10-15 20:17:15
|
Hi there, we are using SWIG to generate C# and Java Bindings for our C++ middleware, which works great! But there is one issue when using directors as arguments to simple proxy classes: The proxy class does not hold a reference to the director and it is collected by the garbage collector as soon as the director goes out of scope. Assume for instance a subscriber proxy class that takes a receiver director. If I instantiate the receiver within the function call to subscriber.setReceiver(new FancyReceiver()), it will immediately be deleted by the next GC run. I managed to work around the issue by renaming the setReceiver method, making it private and add a "wrapper wrapper" which sets a private receiver field in the object: %rename(setReceiverNative) umundo::Subscriber::setReceiver(Receiver*); %javamethodmodifiers umundo::Subscriber::setReceiver(Receiver* receiver) "private"; %typemap(javacode) umundo::Subscriber %{ // keep receiver as a reference to prevent premature GC private Receiver _receiver; protected void setReceiver(Receiver receiver) { // it is important to keep the reference, otherwise the Java GC will eat it! _receiver = receiver; setReceiverNative(receiver); } %} while this works as one would expect, the approach fails if the Receiver is passed to the constructor as one cannot simply rename the constructor, furthermore, we have several such situations and keeping track is somewhat involved. Is there a more elegant approach to keep a reference to director arguments in the proxy classes to prevent premature GC? I always have to remind developers to use the same scope for subscribers and receivers and it fails silently otherwise. Best regards Stefan |