# How to scan a RARRAY?

**URL:** <https://www.ruby-forum.com/t/how-to-scan-a-rarray/111453>\
**Category:** Ruby\
**Created:** [August 7, 2007, 3:02pm UTC](https://www.ruby-forum.com/t/how-to-scan-a-rarray/111453 "2007-08-07T15:02:59Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![unbewust](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/9d8465/32.png) [@unbewust](https://www.ruby-forum.com/u/unbewust)\
**Post date:** [August 7, 2007, 3:02pm UTC](https://www.ruby-forum.com/t/how-to-scan-a-rarray/111453/1 "2007-08-07T15:02:59Z")

</div>

from ruby.h :

struct RArray {  
struct RBasic basic;  
long len;  
union {  
long capa;  
VALUE shared;  
} aux;  
VALUE \*ptr;  
};

my module make use of :  
VALUE m\_set\_icon(VALUE self, VALUE src\_path, VALUE dst\_pathes[])

dst\_pathes is a T\_ARRAY

int len = RARRAY(dst\_pathes)-\>len;  
printf(“len = %d\n”, len);  
char \*cdst\_pathes[len];

how to duplicated the VALUE (shared) from the struct RArray into  
cdst\_pathes (an Array of char \*) ???

i don’t see how to use the VALUE \*ptr, ie. in my case :  
RARRAY(dst\_pathes)-\>ptr

ruby side :

require ‘rseticon’

include RSetIcon

puts "RSetIcon : version = " + version()  
puts "RSetIcon : set\_icon(“aIcon.icns”, [“un”, “deux”, "trois  
"]) = " + set\_icon(“aIcon.icns”, [“un”, “deux”, “trois”]).to\_s

gives the obvious result : [un, deux, trois].

“un”, “deux”, “trois” will be the pathes of files where we want to  
apply the icon “aIcon.icns” (first arg of set\_icon).

then, i want to retrieve, in the C side as a CString the pathes where  
to apply the icon.

i don’t see how to use RARRAY(dst\_pathes)-\>ptr to scan the VALUEs (in  
the union aux) ???

thanks in advance 😉

Yvon

---

<div class="post-metadata">

**Author:** ![unbewust](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/9d8465/32.png) [@unbewust](https://www.ruby-forum.com/u/unbewust)\
**Post date:** [August 7, 2007, 4:21pm UTC](https://www.ruby-forum.com/t/how-to-scan-a-rarray/111453/2 "2007-08-07T16:21:11Z")

</div>

On Aug 7, 8:57 am, unbewust [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> include RSetIcon  
> then, i want to retrieve, in the C side as a CString the pathes where  
> to apply the icon.
> 
> i don’t see how to use RARRAY(dst\_pathes)-\>ptr to scan the VALUEs (in  
> the union aux) ???
> 
> thanks in advance 😉
> 
> Yvon

RArray-\>ptr is a (VALUE \*) pointer to the the first VALUE stored in  
the ruby array.  
RArray-\>len is a count of the number of VALUEs stored in the ruby  
array.  
The VALUEs are stored sequentially.

> From README.EXT (section 1.3)  
> | For example, `RSTRING(str)->len' is the way to get the size of the | Ruby String object. The allocated region can be accessed by | `RSTRING(str)-\>ptr’. For arrays, use `RARRAY(ary)->len' and | `RARRAY(ary)-\>ptr’ respectively.

You shouldn’t need to access the union aux to get to the array values.

For example, with example\_ext.c:  
| #include “ruby.h”  
|  
| /\* print out all the ruby strings in the args array _/  
| static VALUE my\_func( VALUE receiver, VALUE args )  
| {  
| int i;  
| for (i = 0; i \< RARRAY(args)-\>len; i++)  
| {  
| if (TYPE( RARRAY(args)-\>ptr[i] ) == T\_STRING )  
| {  
| printf(“args[%d]: found string "%s"\n”, i,  
RSTRING( RARRAY(args)-\>ptr[i] )-\>ptr );  
| }  
| else  
| {  
| printf(“args[%d]: did not find string\n”, i);  
| }  
| }  
| return Qnil;  
| }  
|  
| static VALUE my\_init( VALUE self )  
| {  
| return self;  
| }  
|  
| VALUE cMyClass;  
| void Init\_example\_ext(void)  
| {  
| /_ define MyClass as a ruby class _/  
| cMyClass = rb\_define\_class(“MyClass”, rb\_cObject);  
|  
| /_ define an initializer for MyClass _/  
| rb\_define\_method(cMyClass, “initialize”, my\_init, 0);  
|  
| /_ define my\_meth as an instance method of MyClass _/  
| /_ dump all the arguments to my\_meth into a ruby array, and pass it  
to my\_func \*/  
| rb\_define\_method(cMyClass, “my\_meth”, my\_func, -2);  
| }

I can do  
| require ‘example\_ext’  
| x = MyClass.new  
| x.my\_meth( “un”, “deux”, “trois”, “quatre”, “cinq”, [], “sept”,  
“huit”, x )

and see  
| args[0]: found string “un”  
| args[1]: found string “deux”  
| args[2]: found string “trois”  
| args[3]: found string “quatre”  
| args[4]: found string “cinq”  
| args[5]: did not find string  
| args[6]: found string “sept”  
| args[7]: found string “huit”  
| args[8]: did not find string

---

<div class="post-metadata">

**Author:** ![unbewust](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/9d8465/32.png) [@unbewust](https://www.ruby-forum.com/u/unbewust)\
**Post date:** [August 7, 2007, 5:13pm UTC](https://www.ruby-forum.com/t/how-to-scan-a-rarray/111453/3 "2007-08-07T17:13:15Z")

</div>

On 8/7/07, unbewust [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> };
> 
> my module make use of :  
> VALUE m\_set\_icon(VALUE self, VALUE src\_path, VALUE dst\_pathes[])

VALUE m\_set\_icon(VALUE self, VALUE src\_path, VALUE dst\_pathes)

> dst\_pathes is a T\_ARRAY
> 
> int len = RARRAY(dst\_pathes)-\>len;  
> printf(“len = %d\n”, len);  
> char \*cdst\_pathes[len];
> 
> how to duplicated the VALUE (shared) from the struct RArray into  
> cdst\_pathes (an Array of char \*) ???

int len = RARRAY(dst\_pathes)-\>len;  
char\* cdst\_pathes[len];

long ii;  
for (ii = 0; ii \< len; ii++) {  
VALUE str = rb\_ary\_entry( dst\_pathes, ii );  
cdst\_pathes[ii] = StringValueCStr( str );  
}

rb\_ary\_entry will return the VALUE from the Array at the given index.

StringValueCStr will check that the given VALUE is a String, and then  
it will return the pointer of that String. This will not give you  
copy, so the memory is still owned by the Ruby interpreter, and it  
will be garbage collected if the original String object goes out of  
scope. You might need to use memcopy to get a copy of the string that  
will not be garbage collected – just depends on how long you’re going  
to need a reference to the data.

Take a look at the Ruby source code for more methods for working with  
Arrays and Strings. ruby.h and intern.h

rb\_ary\_ ← methods that operate on Array objects  
rb\_string\_ ← methods that operate on String objects

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![unbewust](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/9d8465/32.png) [@unbewust](https://www.ruby-forum.com/u/unbewust)\
**Post date:** [August 8, 2007, 11:11am UTC](https://www.ruby-forum.com/t/how-to-scan-a-rarray/111453/4 "2007-08-08T11:11:14Z")

</div>

On 7 août, 17:12, “Tim P.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > ```
> > long capa;
> > 
> > ```
> > 
> > dst\_pathes is a T\_ARRAY
> 
> it will return the pointer of that String. This will not give you  
> rb\_string\_ ← methods that operate on String objects
> 
> Blessings,  
> TwP

OK fine thanks, I’ve found it myself 😉
