Stephen
Stephen

Reputation: 3432

Ruby Extension Data_Wrap_Struct - type Error

I'm trying to create a C wrapper for a library and I've constructed this code which seems to match most of the examples out there on the web:

#include <stdio.h>
#include <stdlib.h>
#include "ruby.h"
#include "lpsolve/lp_lib.h"


VALUE klass;

void lp_free(lprec *lp) {
  delete_lp(lp);
}

VALUE lp_create(VALUE self, VALUE cols) {
  lprec *lp = make_lp(0, NUM2INT(cols));
  if (lp == NULL) {
    rb_raise(rb_eTypeError, "Could not allocate LP Structure");
  }
  return Data_Wrap_Struct(klass, NULL, lp_free, lp);
}


VALUE lp_add_column(VALUE self, VALUE data) {
    lprec *lp;
    Data_Get_Struct(self, lprec, lp);
    return Qnil;
}

void Init_lpsolve_ruby() {
  klass = rb_define_class("LPSolve",    rb_cObject); 
  rb_define_method(klass, "lp_create",  lp_create,     1);
    rb_define_method(klass, "add_column", lp_add_column, 1);
}

Followed with:

s = LPSolve.new
s.lp_create(5)
s.add_column(5)

But I end up with this error:

test.rb:7:in `add_column': wrong argument type LPSolve (expected Data) (TypeError)

What am I doing wrong here?

Thanks.

Upvotes: 3

Views: 149

Answers (1)

Adrian
Adrian

Reputation: 15171

You are misunderstanding the function of Data_Wrap_Struct and Data_Get_Struct. Data_Wrap_Struct allocates a new object that wraps the data. The first argument to Data_Get_Struct must be an object that was returned from Data_Wrap_Struct. Since you do not define a custom allocation function for LPSolve, when you call LPSolve.new a new instance of LPSolve is allocated like any other normal object in ruby (without calling Data_Wrap_Struct), and so you cannot pass the resulting object into Data_Get_Struct.

Upvotes: 2

Related Questions