noah.easterly@gmail.com
8/7/2007 2:19:00 PM
On Aug 7, 8:57 am, unbewust <yvon.thora...@gmail.com> wrote:
> 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
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