Ruby C Extension - TypeError on TypedData_Get_Struct call that is no type error

128 Views Asked by At

I am working on a Ruby C/C++ Extension and thus far it has been going quite well. However I came across an error that I don't know what to do about it.

I have defined the following ruby data types:

static const rb_data_type_t SmartLib_File_type = {
  "SmartLib::File",
  {0, SmartLib_File_free, SmartLib_File_size,},
  0, 0,
  RUBY_TYPED_FREE_IMMEDIATELY,
};

static const rb_data_type_t SmartLib_Plotter_type = {
  "SmartLib::Plotter",
  {0, SmartLib_Plotter_free, SmartLib_Plotter_size,},
  0, 0,
  RUBY_TYPED_FREE_IMMEDIATELY,
};

both those data types are being wrapped by their corresponding C++ classes and represented by Ruby classes:

// SmartLib::File
VALUE SmartLib_File_alloc(VALUE self) {
    /* allocate */
    SmartLib::TransformableFile *data = new SmartLib::TransformableFile();

    /* wrap */
    return TypedData_Wrap_Struct(self, &SmartLib_File_type, data);
}

// SmartLib::Plotter
VALUE SmartLib_Plotter_alloc(VALUE self) {
    /* allocate */
    SmartLib::Plotter *data = new SmartLib::Plotter();

    /* wrap */
    return TypedData_Wrap_Struct(self, &SmartLib_Plotter_type, data);
}

In order to make unwrapping of those C/C++ data easier, I have also two macros defined to help with this:

#define UNWRAP_SMART_FILE(obj, fp) \
    SmartLib::TransformableFile* fp;\
    TypedData_Get_Struct((obj), SmartLib::TransformableFile, &SmartLib_File_type, (fp));

#define UNWRAP_SMART_PLOTTER(obj, pp) \
    SmartLib::Plotter* pp;\
    TypedData_Get_Struct((obj), SmartLib::Plotter, &SmartLib_Plotter_type, (pp));

Now, I have a Ruby method plot in the SmartLib::Plotter class, with the following definition:

VALUE SmartLib_Plotter_plot(VALUE self, VALUE rb_oFile, VALUE rb_sTemplatePath) {
  UNWRAP_SMART_PLOTTER(self, smartPlotter);
  UNWRAP_SMART_FILE(rb_oFile, smartFile);

  // do stuff

  return self;
}

which is callable from Ruby like so:

sf = SmartLib::File.new(file_path)
p  = SmartLib::Plotter.new

p.plot(sf, template_path)

The problem arises on the UNWRAP_SMART_FILE(rb_oFile, smartFile); line int he plot method, so when the corresponding C/C++ data gets unwrapped. Ruby throws an exception:

TypeError:
       wrong argument type SmartLib::File (expected SmartLib::File)

In other areas of the code the call to UNWRAP_SMART_FILE always works as expected. Also the error message clearly doesn't make sense?

Any help is kindly appreciated!

0

There are 0 best solutions below