On Aug 16, 1:00 am, "Gerardo Santana G?mez Garrido"
<gerardo.sant... / gmail.com> wrote:
> 2007/8/15, Tim Hunter <TimHun... / nc.rr.com>:
>
>
>
> > Gerardo Santana G?mez Garrido wrote:
> > > In a C extension I have a function that calls to rb_yield to invoke
> > > the block that the final user will supply.
>
> > > I want to call that function from within that same C extension. The
> > > problem is how to create  and pass a block to this function, in C.
>
> > > Thanks in advance for any advice.
>
> > I think rb_iterate() will do what you want.
>
> > VALUE rb_iterate( VALUE (*method)(), VALUE args, VALUE (*block)(), VALUE
> > arg2 )
> > Invokes method with argument args and block block. A yield from
> > that method will invoke block with the argument given to yield and
> > a second argument arg2.
>
> Thank you Tim, that function is what I was looking for.
>
> But I have another problem. The method I want to call receives the
> following parameters:
>
> int argc, VALUE *argv, VALUE klass
>
> I can't pass those parameters as args.
>
> Any idea?
> --
> Gerardo Santana

I have a more elegant solution that I can't seem to remember right
now, but the most simple way to do this is to pack the args into an
array and pass that array in as the arg to an intermediate function.

for example (I haven't compiled this btw):

//Don't think you need VALUE and/or kls if you aren't accessing from
ruby btw...
static VALUE _hash_add_helper(VALUE my_hash, VALUE some_key, VALUE
some_val)
{
  rb_funcall(my_hash,rb_intern("store"), 2, some_key, some_val);
  return my_hash
}

my_ary = rb_ary_new3(3,my_hash, some_key, some_val);
rb_iterate(rb_each,my_ary,_hash_add_helper,my_ary);

Alternatively, you could use a GetoptLong as the final agrument.  BTW,
arg #2 to rb_iterate, 'args', is the object that responds to arg #1,
'method'.