Question

I'm tryign to build a Ruby C extension that uses some c++ libraries. Problem is I can't even get a simple "hello world" to work.

//hello_world.cpp
#include <ruby.h>


static VALUE tosCore;

static VALUE my_function( VALUE self )
{
    VALUE str = rb_str_new2( "Hello World!" );
    return str;
}

extern "C"
void Init_hello_world( void )
{    
    tosCore = rb_define_module("Core");
    rb_define_module_function(tosCore, "my_method", my_function, 0);   
}

The output I get is

compiling hello_world.cpp
hello_world.cpp: In function 'void Init_hello_world()':
hello_world.cpp:17:67: error: invalid conversion from 'VALUE (*)(VALUE) {aka lon
g unsigned int (*)(long unsigned int)}' to 'VALUE (*)(...) {aka long unsigned in
t (*)(...)}' [-fpermissive]
In file included from c:/Ruby200/include/ruby-2.0.0/ruby.h:33:0,
                 from hello_world.cpp:2:
c:/Ruby200/include/ruby-2.0.0/ruby/ruby.h:1291:6: error:   initializing argument
 3 of 'void rb_define_module_function(VALUE, const char*, VALUE (*)(...), int)'
[-fpermissive]
make: *** [hello_world.o] Error 1

I'm no C/C++ expert. Ruby is my language. I have compiled a few thousand lines of C++ under Rice with no problem, but since I want this particular extension to compile under Windows, Rice is not an option.

Was it helpful?

Solution

It's because the function callback you present to rb_define_module_function is not what the compiler expects. It want a function looking like this:

VALUE my_function(...)

But your function is

VALUE my_function( VALUE self )

Notice the difference in the argument list.

One way to get rid of the error, is to type cast the argument to the type that rb_define_module_function expects:

rb_define_module_function(tosCore, "my_method",
    reinterpret_cast<VALUE(*)(...)>(my_function), 0);

You can read about reinterpret_cast here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top