2015-09-29 44 views
2

我试图创建一个库中的C包装,我已经构建此代码,这似乎符合大多数的例子在那里的网站:Ruby扩展Data_Wrap_Struct - 类型错误

#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); 
} 

其次搭配:

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

但我结束了这个错误:

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

什么我错在这里做什么?

谢谢。

+0

是的,我很抱歉 - 我意识到我需要别的东西,并且klass在调用Data_Wrap_Struct时是正确的变量 - 我一直在这两者之间弹跳。为了记录,我在看到您的回复之前做出了改变! – Stephen

+0

您的错误实际发生在上述代码中吗?看起来你可能在发生错误时有'Data_Get_Struct(klass,lprec,lp);'在'lp_add_column'中的代码?我认为'Data_Get_Struct(self,lprec,lp);'是正确的。 –

+0

是的,我有Data_Get_Struct(self,lprec,lp) - 我只是重新编译一次,以确保我没有任何陈旧的构建或任何东西。 – Stephen

回答

2

您误解了Data_Wrap_StructData_Get_Struct的功能。 Data_Wrap_Struct分配一个包装数据的新对象。 Data_Get_Struct的第一个参数必须是从Data_Wrap_Struct返回的对象。由于您没有为LPSolve定义自定义分配函数,因此当您拨打LPSolve.new时,LPSolve的新实例与Ruby中的任何其他普通对象(未调用Data_Wrap_Struct)一样被分配,因此无法将生成的对象传递到Data_Get_Struct

+0

顺便说一句,我敢打赌,这将适用于你当前的C代码(可能是错误的):'LPSolve.new.lp_create(5).add_column(5)' – Adrian

+0

谢谢,所以整个对象需要被包装? – Stephen

+0

你是对的顺便说一句,第二个工作正常 – Stephen