# Ruby-ffi problem

**URL:** <https://www.ruby-forum.com/t/ruby-ffi-problem/167559>\
**Category:** Ruby\
**Created:** [May 9, 2009, 11:50am UTC](https://www.ruby-forum.com/t/ruby-ffi-problem/167559 "2009-05-09T11:50:30Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aston](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/85f322/32.png) [@Aston](https://www.ruby-forum.com/u/Aston)\
**Post date:** [May 9, 2009, 11:50am UTC](https://www.ruby-forum.com/t/ruby-ffi-problem/167559/1 "2009-05-09T11:50:30Z")

</div>

Hello,

I am trying to learn ruby-ffi now (after sadly leaving dl library), I  
have some trouble here too

I will present a simple example where I want to pass a struct between  
ruby and C  
I am facing problems while setting fields of struct if that field is of  
type string(char\*, not char[])  
I understand we have to allocate the char\* field of struct first than  
assign some literal srting

consider the C file

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* C FILE\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
#include \<stdlib.h\>  
#include \<stdio.h\>  
#include \<string.h\>

typedef struct  
{  
char \*name;  
double val;  
} INFO, \*INFO\_PTR;

INFO\_PTR create( char\* name, double val)  
{  
INFO\_PTR p = (INFO\_PTR)malloc( sizeof(INFO));  
p-\>val = val;  
p-\>name = (char\*)malloc( strlen(name) + 1);  
strcpy( p-\>name, name);  
return p;  
}

int show( INFO\_PTR pInfo)  
{  
return printf( “%s - %f\n”, pInfo-\>name, pInfo-\>val);  
}

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* END C FILE\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* RUBY FILE\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
require ‘ffi’

module LibTest  
class Info \< FFI::Struct  
layout :name, :string,  
:val, :double  
end

extend FFI::Library  
ffi\_lib “./libtest.so”  
attach\_function :create, [:string, :double], :pointer  
attach\_function :show, [:pointer], :int  
end

include FFI

ptr = LibTest.create( “test string”, 11.27)  
obj = LibTest::Info.new(ptr)  
LibTest.show(ptr)  
obj[:val] = 27.11 # this works

# obj[:name] = “new string” # this gives error, `[]=': Cannot set

:string fields (ArgumentError)  
LibTest.show(ptr)  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* END RUBY FILE\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

how can I set string values from ruby ?  
If I refuse to declare name field as type char[] from char\* then I have  
to allocate before I can assign  
then my approach below core dumps ☹

1 str = “test string”  
2 p = MemoryPointer.new( str.size)  
3 p.write\_string(str)  
4 puts p.read\_string # “test string”  
5 obj[:name].write\_pointer(p) # core dumps here!

line # 5 core dumps everytime one tries to write anything there, since  
pointer is invalid I guess  
how do I allocate memory there ? once allocated can i treat that  
allocated memory as ruby string ?

Goal I want to achieve is I shall allocate in ruby, assign in ruby and  
pass in to C code only for modification or read only purpose  
how do I go from here ? can you comment on this ?

Aston

```
  Cricket on your mind? Visit the ultimate cricket website. Enter 

```

> **[Yahoo | Mail, Weather, Search, Politics, News, Finance, Sports & Videos](https://www.yahoo.com/)**
>
> Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!

---

<div class="post-metadata">

**Author:** ![Aston](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/85f322/32.png) [@Aston](https://www.ruby-forum.com/u/Aston)\
**Post date:** [May 9, 2009, 8:19pm UTC](https://www.ruby-forum.com/t/ruby-ffi-problem/167559/2 "2009-05-09T20:19:50Z")

</div>

You probably want to take this to the ruby-ffi project here:

[http://kenai.com/projects/ruby-ffi](http://kenai.com/projects/ruby-ffi)

---

<div class="post-metadata">

**Author:** ![Aston](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/85f322/32.png) [@Aston](https://www.ruby-forum.com/u/Aston)\
**Post date:** [May 10, 2009, 1:56am UTC](https://www.ruby-forum.com/t/ruby-ffi-problem/167559/3 "2009-05-10T01:56:55Z")

</div>

If you want to change the string value of a field in a struct through  
FFI, I suggest using the “:pointer” rather than “:string”.

=cut

require ‘rubygems’  
require ‘ffi’

module LibTest  
class Info \< FFI::Struct  
layout :name, :pointer,  
:val, :double  
end

extend FFI::Library  
ffi\_lib ‘./libtest.dylib’  
attach\_function :create, [:string, :double], :pointer  
attach\_function :show, [:pointer], :int  
end

include FFI

ptr = LibTest.create( “test string”, 11.27)  
obj = LibTest::Info.new(ptr)  
LibTest.show(ptr)  
obj[:val] = 27.11  
obj[:name].put\_bytes(0,‘new string’)  
LibTest.show(ptr)

=end

In the long run, as Charlie suggested, your question will be better  
answered by ruby-ffi project.

–  
Hirotsugu A.
