加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

将C结构包装到Ruby

发布时间:2020-12-16 06:59:36 所属栏目:百科 来源:网络整理
导读:如何初始化C Struct并将其包装为 Ruby类作为另一个 Ruby对象的参数?我正在重写内存,但不知道,如何解决它. Ruby代码,我想创建Person类的实例并在其中添加Address变量,这是另一个类: require_relative 'my_extension'class Address def inspect "Replaced #i
如何初始化C Struct并将其包装为 Ruby类作为另一个 Ruby对象的参数?我正在重写内存,但不知道,如何解决它.

Ruby代码,我想创建Person类的实例并在其中添加Address变量,这是另一个类:

require_relative 'my_extension'

class Address
  def inspect
    "Replaced #inspect: <Address: town:#{town}>"
  end
end

class Person
    def initialize
        puts "init"
    end

    def print()
        puts "Addr class #{@addr.inspect}"
    end
end

foo1=Person.new
foo1.add_address("London")
foo1.print
foo2=Person.new
foo2.add_address("Paris")
foo1.print
foo2.print
foo1.print

C代码,扩展Ruby:

#include <stdio.h>
#include "ruby.h"

struct Address {
    char * town;
};

static VALUE get_addr(VALUE self) {
    return rb_iv_get(self,"@addr");
}

static VALUE wrap_address_get_town(VALUE self) {

    struct Address * address;
    Data_Get_Struct(self,struct Address,address);
    return rb_str_new2(address->town);
}


VALUE foo_class;
VALUE address_wrapper_class;


void free_m(){
    printf("freen");//just for test
}

void add_address_t(VALUE self,VALUE new_town){
    printf("add_addressn");
    /*init new struct and add value to it*/
    struct Address addr;
    addr.town=StringValuePtr(new_town);

    /*wrap struct*/
    VALUE wrapped_address=Data_Wrap_Struct(address_wrapper_class,free_m,&addr);

    /*set it as instance variable*/
    rb_iv_set(self,"@addr",wrapped_address);
}

static VALUE foo_class_alloc(VALUE self){
    return self;
}


void Init_my_extension(){
    foo_class = rb_define_class("Person",rb_cObject);

    address_wrapper_class = rb_define_class("Address",rb_cObject);

    rb_define_method(address_wrapper_class,"town",wrap_address_get_town,0);

    rb_define_method(foo_class,"add_address",add_address_t,1);

}

输出产生意外结果:

init
Addr class Replaced #inspect: <Address: town:London>
init
Addr class Replaced #inspect: <Address: town:Paris> //London expected
Addr class Replaced #inspect: <Address: town:?)> //another problem
Addr class Replaced #inspect: <Address: town:?)>
run
run
free
free

解决方法

应将所有C例程定义为静态返回VALUE.这应该是Qnil,如果不应该返回任何相关的.还有另一个问题,使用add_address_t例程 – 你正在包装一个本地定义的结构 – 它应该用ALLOC(struct Address)分配;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读