[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Creating and passing a block in a C extension

Gerardo Santana Gómez Garrido

8/15/2007 10:19:00 PM

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.

--
Gerardo Santana
"Between individuals, as between nations, respect for the rights of
others is peace" - Don Benito Juárez
http://santanatechnotes.blo...

4 Answers

Tim Hunter

8/15/2007 10:52:00 PM

0

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.

--
RMagick OS X Installer [http://rubyforge.org/project...]
RMagick Hints & Tips [http://rubyforge.org/forum/forum.php?for...]
RMagick Installation FAQ [http://rmagick.rubyforge.org/instal...]


Gerardo Santana Gómez Garrido

8/16/2007 5:00:00 AM

0

2007/8/15, Tim Hunter <TimHunter@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

Tim Hunter

8/16/2007 12:54:00 PM

0

On Aug 16, 1:00 am, "Gerardo Santana Gómez Garrido"
<gerardo.sant...@gmail.com> wrote:
> 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.

Both the "args" passed to the method and "arg2" passed to the block
can be an array.

Tom M

8/16/2007 1:01:00 PM

0

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'.