【问题标题】:What am I supposed to return as class in Data_Wrap_Struct?我应该在 Data_Wrap_Struct 中作为类返回什么?
【发布时间】:2011-06-23 18:50:03
【问题描述】:

这是我的精简代码,可以隔离我的问题:

#include "ruby.h"
#include "stdlib.h"

typedef struct HandValues {
    double pair1;
    double pair2;
} HandValues;

static VALUE 
get_pairs_2(self) 
  VALUE self;
{

    HandValues *MadeHand = (HandValues *) malloc(sizeof(HandValues));
    MadeHand->pair1 = 5;

    return Data_Wrap_Struct(self, NULL, NULL, &MadeHand);
}

void Init_ev() {
    rb_eval_string("require './lib/ev/pair_counter'");
    VALUE PairCounter = rb_path2class("EV::PairCounter");
    rb_define_method(PairCounter, "get_pairs_2", get_pairs_2, 0);
}

当我在 ruby​​ 中调用 get_pairs_2 时,出现此错误:

TypeError: wrong argument type EV::PairCounter (expected Class)

我已确认 C 将 EV::PairCounter 视为超类,而不是字符串或其他东西。

顺便说一句,这就是 C 扩展 API 关于 Data_Wrap_Struct 的说法:

将 C 数据封装到 Ruby 对象中

要将 C 指针包装和对象化为 Ruby 对象(所谓的 DATA),请使用 Data_Wrap_Struct()。

Data_Wrap_Struct(klass, mark, free, ptr)

Data_Wrap_Struct() 返回一个创建的 DATA 对象。 klass 参数是 DATA 对象的类。 mark 参数是标记该数据指向的 Ruby 对象的函数。 free 参数是释放指针分配的函数。如果这是-1,指针将被释放。垃圾回收器会调用mark和free函数。

【问题讨论】:

  • 如果你有自己的stdlib.h,你真的应该给它取个不同的名字;如果您依赖实现stdlib.h,正确的行是#include <stdlib.h> :)
  • VALUE self; 放在函数签名和主体之间的目的到底是什么?
  • @JAB:这是旧式声明。最近(1989 年之后)我们开始使用原型代替;但是编译器大多是向后兼容的,并且(除非你要求他们抱怨)安静地接受旧语法。
  • @pmg:你忘了告诉他离开你的草坪。

标签: c ruby ruby-c-extension


【解决方案1】:

问题是 Data_Wrap_Struct(klass, mark, free, ptr) 中的 klass 是您要返回的 klass,而不是您要将数据发送到的 klass。所以 klass 是一个用 C 定义和填充的 ruby​​ 类,然后用这个函数返回给 ruby​​。

【讨论】:

  • 例如 ' static VALUE createMat4(VALUE obj) { void *p=malloc(sizeof(double)*16); printf("创建 %p\n",p);价值诉; v=Data_Wrap_Struct(v, NULL, NULL, p);返回 v; }'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 2019-09-18
  • 1970-01-01
  • 2011-03-09
相关资源
最近更新 更多