# Yet another question about extending ruby with C

**URL:** <https://www.ruby-forum.com/t/yet-another-question-about-extending-ruby-with-c/136800>\
**Category:** Ruby\
**Created:** [May 6, 2008, 2:49pm UTC](https://www.ruby-forum.com/t/yet-another-question-about-extending-ruby-with-c/136800 "2008-05-06T14:49:50Z")\
**Posts on this page:** 3\
**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 6, 2008, 2:49pm UTC](https://www.ruby-forum.com/t/yet-another-question-about-extending-ruby-with-c/136800/1 "2008-05-06T14:49:50Z")

</div>

Hello all,

I’m still working on figuring how how to extend ruby with C libraries.  
Hope someone can help me with this one!

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

---

<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 7, 2008, 3:51am UTC](https://www.ruby-forum.com/t/yet-another-question-about-extending-ruby-with-c/136800/2 "2008-05-07T03:51:36Z")

</div>

Bryan R. wrote:

> Say I have the following:
> 
> typedef struct {  
> char\* name;  
> } Foo;
> 
> […]
> 
> 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;  
> }
> 
> […]
> 
> If I do the following, everything works perfectly and I see my name  
> printed  
> on the screen:
> 
> […]  
> b.test(f) // prints “Bryan”

“works perfectly”? I don’t see how it can print “Bryan”, for two  
reasons:

1. It’s supposed to print “Name: Bryan”, not “Bryan”.

2. But it can’t print “Name: Bryan” either. That’s because in foo\_init()  
you aren’t settings f-\>name to “Bryan”. Instead, you’re settings an  
instance variable, “@name”, to “Bryan”. It happens that “@name” has a  
similar name to char \*name, but these two variables aren’t related at  
all.

Last but not least:

If you want ppl to help you, you must make it easier for them to help  
you. Do that by choosing _sane_ names for your  
methods/structures/variables. I had a hard time following your code (and  
that in your previous question). ‘test’, ‘Test’ and ‘Foo’ aren’t  
meaningful names. Change them to make\_person, Person, and person\_rec.

---

<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 7, 2008, 4:02am UTC](https://www.ruby-forum.com/t/yet-another-question-about-extending-ruby-with-c/136800/3 "2008-05-07T04:02:11Z")

</div>

Hi Albert,

Thanks for responding. Sorry for not making things clear and easy to  
follow… I was in a hurry when I wrote it. 😕 I’ll try and clear  
things up when I have a chance. Thanks again!

–  
Bryan
