# Need more help with Ruby and C

**URL:** <https://www.ruby-forum.com/t/need-more-help-with-ruby-and-c/136648>\
**Category:** Ruby\
**Created:** [May 5, 2008, 5:13am UTC](https://www.ruby-forum.com/t/need-more-help-with-ruby-and-c/136648 "2008-05-05T05:13:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![roxah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/54ee81/32.png) [@roxah](https://www.ruby-forum.com/u/roxah)\
**Post date:** [May 5, 2008, 5:13am UTC](https://www.ruby-forum.com/t/need-more-help-with-ruby-and-c/136648/1 "2008-05-05T05:13:44Z")

</div>

Hello all,

So I have something like the following in my C file:

static VALUE rb\_cBar;

static VALUE foo\_new() {  
VALUE new\_foo;  
…  
return new\_foo;  
}

static VALUE execute(VALUE foos) {  
VALUE foo = rb\_ary\_entry(foos, 0);  
printf(“Foo Value: %i\n”, rb\_iv\_get(foo, “@value”);  
}

void Init\_bar() {  
rb\_cBar = rb\_define\_class(“Bar”, rb\_cObject);  
rb\_define\_method(rb\_cBar, “new\_foo”, foo\_new, 0);  
rb\_define\_method(rb\_cBar, “execute”, execute, 1);  
}

and in my Ruby file I do the following:

require ‘bar’

b = Bar.new  
a = Array.new  
a \<\< b.new\_foo  
b.execute(a)

My question is with the execute method. It outputs 0.00 when it should  
output 1.01 (there’s a foo\_init method called that I didn’t include here  
that sets the value variable of the foo struct to 1.01). I assume this  
doesn’t work because I’m passing the execute method an array created in  
Ruby code and not an array created using the C functions. Is there some  
way I can do it the way I’m trying to above?

–  
Thanks!  
Bryan

---

<div class="post-metadata">

**Author:** ![roxah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/54ee81/32.png) [@roxah](https://www.ruby-forum.com/u/roxah)\
**Post date:** [May 5, 2008, 8:59am UTC](https://www.ruby-forum.com/t/need-more-help-with-ruby-and-c/136648/2 "2008-05-05T08:59:20Z")

</div>

On May 4, 2008, at 20:13 , Bryan R. wrote:

> Hello all,
> 
> So I have something like the following in my C file:
> 
> static VALUE rb\_cBar;
> 
> static VALUE foo\_new() {  
> VALUE new\_foo;  
> …

^^^ problem exists here. can’t help any further.

---

<div class="post-metadata">

**Author:** ![roxah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/54ee81/32.png) [@roxah](https://www.ruby-forum.com/u/roxah)\
**Post date:** [May 5, 2008, 2:32pm UTC](https://www.ruby-forum.com/t/need-more-help-with-ruby-and-c/136648/3 "2008-05-05T14:32:07Z")

</div>

On Monday 05 May 2008 05:13:49 Bryan R. wrote:

> static VALUE foo\_new() {

> static VALUE execute(VALUE foos) {

ruby passes ‘self’ (current context) as the first argument of any C  
defined  
method, so you have to define it as:

> static VALUE foo\_new(VALUE self) {

> static VALUE execute(VALUE self, VALUE foos) {

Jan

---

<div class="post-metadata">

**Author:** ![roxah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/54ee81/32.png) [@roxah](https://www.ruby-forum.com/u/roxah)\
**Post date:** [May 5, 2008, 6:38pm UTC](https://www.ruby-forum.com/t/need-more-help-with-ruby-and-c/136648/4 "2008-05-05T18:38:46Z")

</div>

On Monday 05 May 2008 15:44:03 Bryan R. wrote:

> Hi Jan,
> 
> Alright, that makes sense, thanks for the information. However, that  
> doesn’t help me to understand how I can pass a Ruby array of objects to the  
> execute method. Am I missing something here? Can you help me with this?

The array is just an object (everything in ruby is object) which you can  
manipulate from C with rb\_ary\_\* functions. You wrote the code yourself:

VALUE foo = rb\_ary\_entry(foos, 0); // this will return the first  
element of  
the array

now, rb\_\* functions operate on (and returns) ruby objects (VALUE), if  
you want  
to direclty use POD data types in C, you have to convert them, e.g. :

VALUE val = rb\_iv\_get(foo,"@value");  
printf(“Foo Value: %i\n”, NUM2INT(val));

or alternatively

printf(“Foo Value: %i\n”, NUM2INT(rb\_iv\_get(foo, “@value”));

For integral types there are general macros INT2NUM (c to ruby) and  
NUM2INT  
(ruby to C), and their variants (FIX2INT,INT2FIX,…), for floats/doubles  
there is NUM2DBL (ruby to c) and rb\_float\_new() (C to ruby).

Also, every method in ruby must return value, so if your function does  
not  
return anything, you have to explicitly return ‘nil’ with

return Qnil;

Jan

---

<div class="post-metadata">

**Author:** ![roxah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/54ee81/32.png) [@roxah](https://www.ruby-forum.com/u/roxah)\
**Post date:** [May 5, 2008, 8:48pm UTC](https://www.ruby-forum.com/t/need-more-help-with-ruby-and-c/136648/5 "2008-05-05T20:48:37Z")

</div>

Jan,

Awesome… this now works perfectly! Also, thanks for the heads-up on  
having to return a value and using Qnil. I was getting a segmentation  
fault  
in irb that I wasn’t sure about and it was because I wasn’t returning  
anything.

One side question… why is it called ‘Qnil’? What is the ‘Q’ for?

–  
Thanks again!  
Bryan

---

<div class="post-metadata">

**Author:** ![roxah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/54ee81/32.png) [@roxah](https://www.ruby-forum.com/u/roxah)\
**Post date:** [May 5, 2008, 3:45pm UTC](https://www.ruby-forum.com/t/need-more-help-with-ruby-and-c/136648/6 "2008-05-05T15:45:45Z")

</div>

Hi Jan,

Alright, that makes sense, thanks for the information. However, that  
doesn’t help me to understand how I can pass a Ruby array of objects to  
the  
execute method. Am I missing something here? Can you help me with  
this?

–  
Thanks!  
Bryan

---

<div class="post-metadata">

**Author:** ![roxah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/54ee81/32.png) [@roxah](https://www.ruby-forum.com/u/roxah)\
**Post date:** [May 5, 2008, 11:42pm UTC](https://www.ruby-forum.com/t/need-more-help-with-ruby-and-c/136648/7 "2008-05-05T23:42:18Z")

</div>

Okay, new question… still in line with what I’ve been asking already.  
Say  
I have the following:

typedef struct {  
char\* name;  
} Foo;

static VALUE rb\_cBar;  
static VALUE rb\_cTest;

static VALUE foo\_new(VALUE self) {  
Foo\* f;  
VALUE info;  
info = Data\_Make\_Struct(rb\_cTest, Foo, 0, free, f);  
rb\_obj\_call\_init(info, 0, 0);  
return info;  
}

static VALUE foo\_init(VALUE self) {  
VALUE str;  
char\* name = “Bryan”;  
str = rb\_str\_new2(name);  
rb\_iv\_set(self, “@name”, str);  
return self;  
}

static VALUE test(VALUE self, VALUE arg) {  
Foo\* f;  
Data\_Get\_Struct(arg, Foo, f);  
printf(“Name: %s\n”, f-\>name);  
return Qnil;  
}

void Init\_power\_flow() {  
rb\_cBar = rb\_define\_class(“Bar”, rb\_cObject);  
rb\_cTest = rb\_define\_class(“Test”, rb\_cObject);  
rb\_define\_method(rb\_cBar, “test”, test, 1);  
rb\_define\_method(rb\_cBar, “new\_foo”, foo\_new, 0);  
rb\_defien\_method(rb\_cTest, “initialize”, foo\_init, 0);  
}

If I do the following, everything works perfectly and I see my name  
printed  
on the screen:

b = Bar.new  
f = b.new\_foo  
b.test(f) // prints “Bryan”

However, say I change the foo\_new method to be the following:

static VALUE foo\_new(VALUE self) {  
Foo\* f;  
VALUE info;  
f = ALLOC(Foo);  
f-\>name = “Bryan”;  
info = Data\_Wrap\_Struct(self, 0, free, f);  
return info;  
}

and I change the method declaration in Init to be the following:

rb\_define\_method(rb\_cTest, “initialize”, foo\_new, 0);

Now, when I do what I did before, I get an error:

b = Bar.new  
f = Test.new  
b.test(f) // TypeError: wrong argument type Test (expected Data)

Any idea why trying to define a constructor rather than a ‘factory’  
method  
is causing me issues?

–  
Thanks in advance!  
Bryan
