ruby callback issue (no implicit conversion of nil into String)

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

ruby callback issue (no implicit conversion of nil into String)

Luis C
Hi,

The following code was working with swig 3.0 and with ruby < 2.3. So probably the problem is on the ruby interpreter. However, because I just swig to wrap the classes may be is something wrong on the definition or I miss something. I got the error "no implicit conversion of nil into String (TypeError)" from the callback but if I access from a new instance, works. This have been working in old versions of ruby. Any similar problems?

File compile.sh
#!/bin/bash

swig -globalmodule -c++ -ruby ruby_wrapper.i    
g++ -fPIC -std=c++11 -I/usr/include/ruby -c Callback.cc ruby_wrapper_wrap.cxx
g++ -fPIC -shared -std=c++11 Callback.o ruby_wrapper_wrap.o -o example.so -lruby

File Callback.h
#ifndef SRC_CALLBACK_H_
#define SRC_CALLBACK_H_

#include <iostream>
#include "MyClass.h"
#include <ruby.h>


class Callback
{
public:
    Callback():callback_set_(false),callback_(Qnil),memory_wrapper_(Qnil),cc("another") {
        memory_wrapper_ = Data_Wrap_Struct(0 /* klass */, staticMark, NULL, static_cast<void*>(this));
        rb_gc_register_address(&memory_wrapper_);

    }
    virtual ~Callback() { rb_gc_unregister_address(&memory_wrapper_);}

    bool haveCallback() const { return callback_set_;}
   
    void setCallback(VALUE callback);
    void executeCallback(MyClass *c);

    void run();
   
protected:
    static void staticMark(Callback *me) { me->mark(); }

    void mark();
private:
    bool callback_set_;
    VALUE callback_;
    VALUE memory_wrapper_;
    MyClass cc;
};

#endif  // SRC_CALLBACK_H_

File Callback.cc
#include "Callback.h"

void Callback::setCallback(VALUE callback) {

    if (!NIL_P(callback)) {
        // Verify the number of arguments of the callback by calling the method arity

        VALUE value = rb_funcall(callback,rb_intern("arity"),0);
        int nargs = NUM2INT(value);

        if (nargs != 1) {
            rb_raise(rb_eRuntimeError,"Object should have one parameter.\n");
        }   

            callback_ = callback;
                callback_set_ = true;
    } else {
            callback_ = Qnil;
                callback_set_ = false;
    }
}


void Callback::executeCallback(MyClass *c) {

    if (!NIL_P(callback_)) {
        ID id = rb_intern("MyClass");
        if (rb_const_defined(rb_cObject, id)) {   
                        VALUE rbClass = rb_const_get(rb_cObject,id);
                    VALUE rbData = Data_Wrap_Struct(rbClass, 0, 0, c);   
                   rb_funcall(callback_,rb_intern("call"), 1, rbData);
        }
        }
}

void Callback::run() {

    executeCallback(&cc);
}


void Callback::mark() {

    if (!NIL_P(callback_)) {
            rb_gc_mark(callback_);
        }
}

File MyClass.h
#ifndef SRC_MYCLASS_H_
#define SRC_MYCLASS_H_

#include <iostream>


class MyClass
{
public:
    MyClass():name_("default value"),value_(0) {}
    MyClass(const std::string name): name_(name),value_(0) {}
    virtual ~MyClass() {}

    int getInt() { return value_; }
    void setInt(int value) { value_ = value; }

    const char *getName() const { return name_.c_str(); }
private:
    std::string name_;   
    int value_;
};

#endif

File ruby_wrapper.i
%module(directors="1") example
%include <std_string.i>

%{
#include <iostream>
#include "Callback.h"
#include "MyClass.h"

using namespace std;
%}

%trackobjects;

%rename("my_name") MyClass::getName;
%rename("my_int") MyClass::getInt;
%rename("my_int=") MyClass::setInt;
%rename("callback=") Callback::setCallback;

%include "MyClass.h"
%include "Callback.h"

File test.rb
require './example'

def callback(cc)
  print("From the callback")
  print(cc.methods.sort)
  print(cc.my_int)
  print(cc.my_name)
end

puts "Testing example"

a = MyClass.new()

print("From the main")
print(a.methods.sort)
puts a.my_name
puts a.my_int

c = Callback.new()

c.callback = method(:callback)

c.run()

This code is working in ruby versions < 2.1, Any one have this problem? other way to pass the object as parameter to the callback?

Thanks and regards,
Luis

------------------------------------------------------------------------------

_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user
Loading...