I am trying to understand some aspects of writing a ruby extension in
C++.
Actually what I am trying to do is wrap a C++ library and make it
accessible from ruby. Since I have been having problems with the library
that I am trying to wrap, I decided to create a really simple library
and try wrapping that.
The biggest problem that I am having is understanding scope. When I
create the wrapper for the class I create a new instance of the class
that I am wrapping and store it in a ptr. Then when I want to access
methods of this class the wrapper class just delegates to the ptr.
Simple stuff.
When I use a regular ptr things mostly work OK except that I can only
create one instance of the class.
The library I am trying to wrap uses smart pointers, so I created a
version of my code that uses simple pointers. The problem that I have
hear is that these objects then fall out of scope and the destructors
get called immediately after wrapper class method exists. The result of
course is that I get segmentation faults or weird results.
I have only a little experience in C++ and this is my first extension
that I have written.
How should I go about wrapping these c++ classes?
Thanks in advance.
Here is the code....
//extension.cpp
#include <ruby.h>
#include <test.h>
#include <smartptr.h>
typedef VALUE (ruby_method)(...);
auto_ptr<Test> test;
//test* test;
extern "C" VALUE t_TEST_init(VALUE self, VALUE value )
{
Param * param = new Param( NUM2INT( value ) );
test = auto_ptr<Test>( new Test( param ) );
//test = new Test( param );
return self;
}
extern "C" VALUE t_TEST_value(VALUE self)
{
return INT2NUM( test->ParamValue() );
}
auto_ptr<Param> param;
//Param* param;
extern "C" VALUE t_PARAM_init(VALUE self, VALUE value )
{
param = auto_ptr<Param>( new Param( 7 ) );
//param = new Param( NUM2INT( value ) );
return self;
}
extern "C" VALUE t_PARAM_value(VALUE self)
{
return INT2NUM( param->value() );
}
VALUE cTest;
VALUE cParam;
extern "C" void Init_Extension()
{
cTest = rb_define_class( "Test", rb_cObject );
rb_define_method( cTest, "initialize", (ruby_method*)
&t_TEST_init, 1 );
rb_define_method( cTest, "value", (ruby_method*) &t_TEST_value,
0 );
cParam = rb_define_class( "Param", rb_cObject );
rb_define_method( cParam, "initialize", (ruby_method*)
&t_PARAM_init, 1 );
rb_define_method( cParam, "value", (ruby_method*)
&t_PARAM_value, 0 );
}
//test.h
#include <param.h>
class Test {
public:
Test(Param *);
~Test();
int ParamValue();
private:
Param *param;
};
//param.h
class Param {
public:
Param(int);
~Param();
int value();
private:
int internal;
};
···
--
Posted via http://www.ruby-forum.com/.