I created a sample ruby extension using C++ class. it works fine when i did not parse the value. but when i parse parameter it show an error. here is my code.
C++ header file
#ifndef CIRCLE_H_
#define CIRCLE_H_
class Circle {
public:
Circle(float radius):_radius(radius) {}
float getArea() { return 3.14159 * _radius * _radius; }
private:
float _radius;
};
CPP file.
#include<ruby.h>
#include"Circle.h"
VALUE method_test(VALUE y){
double x= NUM2DBL(y);
Circle *cir= new Circle(x);
return DBL2NUM(cir->getArea());
}
extern "C" void Init_Test(){
VALUE lemon = rb_define_module("Test");
rb_define_method(lemon, "test", (VALUE(*)(ANYARGS))method_test,1);
}
extconf.rb
require 'mkmf'
have_library( 'stdc++' );
$CFLAGS << " -Wall"
create_makefile( 'Test' );
run.rb
require 'rubygems'
require 'Test'
include Test
puts test(7)
when i execute run.rb it shows an error.
run.rb:7:in `test': can't convert Object into Integer (TypeError)
from run.rb:7:in `<main>'
please help me to solve this problem. thank you.
The line
VALUE method_test(VALUE y) {
Should be
VALUE method_test(VALUE self, VALUE y) {
The error message is thrown by NUM2INT(y)
because y
is the root Object
of the script in your code as-is. The root object is what you got because you mixed in your module at the top level of the script. If you had mixed in to another class, you would have got an instance of that class instead.
All native extension methods should take a self
parameter (the first one if you have fixed number of params) which is the context that they are being called in (a Module
, Class
or instance of a Class
). It is how you get foo
into the extension when you call foo.test
. This might seem odd when both Ruby and C++ do this automatically (self
in Ruby, and this
in C++): However it is necessary to have self
appear as param because the Ruby internal API is written in C, which does not support OO directly - instead the Ruby API defined in ruby.h
expects you to write and use C functions that take references to the current object as one of the params.
In addition you are making a call to Circle( int radius )
- which does not exist (although the compiler may be kind and coerce x
for you automatically). You probably want to use double
variables throughout and use NUM2DBL(y)
and DBL2NUM( cir->getArea() )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With