2

This is my stripped down code which isolates my problem:

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

When I call get_pairs_2 in ruby, I get this error:

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

I've confirmed that C is viewing EV::PairCounter as a superclass, and not as a string or something.

By the way, this is what the C extension API says about Data_Wrap_Struct:

Encapsulate C data into Ruby object

To wrap and objectify a C pointer as a Ruby object (so called DATA), use Data_Wrap_Struct().

Data_Wrap_Struct(klass, mark, free, ptr)

Data_Wrap_Struct() returns a created DATA object. The klass argument is the class for the DATA object. The mark argument is the function to mark Ruby objects pointed by this data. The free argument is the function to free the pointer allocation. If this is -1, the pointer will be just freed. The functions mark and free will be called from garbage collector.

Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
Jeremy Smith
  • 14,727
  • 19
  • 67
  • 114
  • If you have your own `stdlib.h` you really should name it something different; if you rely on the implementations `stdlib.h`, the proper line is `#include ` :) – pmg Jun 23 '11 at 18:54
  • What exactly is the purpose of putting `VALUE self;` between the function signature and body? – JAB Jun 23 '11 at 19:00
  • @JAB: that's old style declaration. Recently (after 1989) we started using prototypes instead; but compilers are mostly backwards compatible and (unless you ask them to complain) quietly accept the old syntax. – pmg Jun 23 '11 at 19:07
  • 2
    @pmg: You forgot to tell him to get off your lawn. – mu is too short Jun 23 '11 at 19:15

1 Answers1

1

The issue was that klass in Data_Wrap_Struct(klass, mark, free, ptr) is the klass you are returning, not the klass you are sending the data to. So klass is a ruby class defined and populated in C, and then returned to ruby with this function.

Jeremy Smith
  • 14,727
  • 19
  • 67
  • 114
  • for example ' static VALUE createMat4(VALUE obj) { void *p=malloc(sizeof(double)*16); printf("create %p\n",p); VALUE v; v=Data_Wrap_Struct( v, NULL, NULL, p ); return v; }' – Chris Camacho Jul 21 '12 at 12:10