[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

"add" function in swig and the ruby GC?

Richard P. Groenewegen

10/24/2004 9:51:00 PM

Hi,

I'm trying to write an add-function in C++ with swig, but I think that
ruby does not Garbage collect my objects. Example:

class Thingy {
public:
Thingy() { }
~Thingy() { cout << "Thingy is destructed."; }

Thingy *add(const Thingy *other) const {
Thingy *result = new Thingy();
// ...
return result;
}
}

Using GC.start I can check that ruby does not destruct Thingies made
with "add". So, what is the correct way to do this? I could return a
Thingy instead of a Thingy*, but is this the preferred(TM) way?

best regards,
Richard


4 Answers

Paul Brannan

10/25/2004 3:28:00 PM

0

On Mon, Oct 25, 2004 at 06:51:21AM +0900, Richard P. Groenewegen wrote:
> class Thingy {
> public:
> Thingy() { }
> ~Thingy() { cout << "Thingy is destructed."; }
>
> Thingy *add(const Thingy *other) const {
> Thingy *result = new Thingy();
> // ...
> return result;
> }
> }

First of all, Ruby will never collect result in the case that an
exception is thrown. Better would be to write:

Thingy *add(const Thingy *other) const {
std::auto_ptr<Thingy> result(new Thingy);
// ...
return result.release();
}

Secondly, because of Ruby's conservative GC, there is no guarantee that
the objects will ever be destroyed as long as your program is running.
If you need to be able to guarantee that a particular resource (e.g. a
socket or a lock) needs to be freed, you will be better off not relying
on the garbage collector but instead using a different mechanism, such
as blocks or an explicit method call to free the resource.

Now that we have that out of the way, you're probably still wondering
why your objects don't get cleaned up. Well, swig should clean up your
objects, but depending on how you've written your swig interface file
and/or your ruby script, that might not happen. Try to post the
smallest complete interface file and script that demonstrates the
problem, and then the answer may be more obvious.

Paul



Richard P. Groenewegen

10/25/2004 8:08:00 PM

0

> Try to post the smallest complete interface file and script that
> demonstrates the problem, and then the answer may be more obvious.

Thanks for the reply and the comment about auto_ptr. I'll be using
that. As for the smallest complete example:

//-------------------------------------------------------------------
// thingy.h
//-------------------------------------------------------------------
#include <iostream>
using namespace std;
class Thingy {
public:
Thingy() {
_number = ++number;
cout << "Thingy " << _number << " constructed.\n";
}
~Thingy() {
cout << "Thingy " << _number << " destructed.\n";
}
Thingy * add(Thingy *other) {
return new Thingy();
}
static int number;
protected:
int _number;
};

//-------------------------------------------------------------------
// thingy.cxx
//-------------------------------------------------------------------
#include "thingy.h"
int Thingy::number = 0;

//-------------------------------------------------------------------
// thingy.i
//-------------------------------------------------------------------
%module thingy

%{
#include "thingy.h"
%}

%include "thingy.h"

//-------------------------------------------------------------------
// irb output (slightly trimmed):
//-------------------------------------------------------------------
irb> require 'thingy.so'
irb> a = Thingy::Thingy.new
Thingy 1 constructed.

irb> b = Thingy::Thingy.new
Thingy 2 constructed.

irb> c = a.add(b)
Thingy 3 constructed.

irb(main):005:0> a,b,c, = 0,0,0

irb(main):006:0> GC.start
Thingy 2 destructed.
Thingy 1 destructed.

As you can see. Thingy 3 does not get destructed. I tried changing
the function add to

void add(Thingy *other, Thingy *OUTPUT) {
OUTPUT = new Thingy();
}

and include "typemaps.i" in the thingy.i file as (sort of) is
suggested in the swig documentation but that does not work.


best regards,
Richard



Tobias Peters

10/25/2004 10:32:00 PM

0

Richard P. Groenewegen wrote:
> Hi,
>
> I'm trying to write an add-function in C++ with swig, but I think that
> ruby does not Garbage collect my objects. Example:
>
> class Thingy {
> public:
> Thingy() { }
> ~Thingy() { cout << "Thingy is destructed."; }
>
> Thingy *add(const Thingy *other) const {
> Thingy *result = new Thingy();
> // ...
> return result;
> }
> }
>
> Using GC.start I can check that ruby does not destruct Thingies made
> with "add". So, what is the correct way to do this? I could return a
> Thingy instead of a Thingy*, but is this the preferred(TM) way?

How could SWIG or Ruby possibly know that the pointer returned by your
add method points to a newly created object on the heap. Swig does not
interpret C++ Code, only types and signatures.

The solution to your problem is in the fine SWIG manual. Hint: %newobject

Tobias

Asbjørn Reglund Thorsen

10/26/2004 7:24:00 AM

0