# Creating and passing a block in a C extension

**URL:** <https://www.ruby-forum.com/t/creating-and-passing-a-block-in-a-c-extension/112162>\
**Category:** Ruby\
**Created:** [August 16, 2007, 12:20am UTC](https://www.ruby-forum.com/t/creating-and-passing-a-block-in-a-c-extension/112162 "2007-08-16T00:20:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/c37758/32.png) [@Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/u/Gerardo_SSGSSS_mez)\
**Post date:** [August 16, 2007, 12:20am UTC](https://www.ruby-forum.com/t/creating-and-passing-a-block-in-a-c-extension/112162/1 "2007-08-16T00:20:59Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/c37758/32.png) [@Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/u/Gerardo_SSGSSS_mez)\
**Post date:** [August 16, 2007, 12:53am UTC](https://www.ruby-forum.com/t/creating-and-passing-a-block-in-a-c-extension/112162/2 "2007-08-16T00:53:01Z")

</div>

Gerardo S. 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.

---

<div class="post-metadata">

**Author:** ![Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/c37758/32.png) [@Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/u/Gerardo_SSGSSS_mez)\
**Post date:** [August 16, 2007, 7:01am UTC](https://www.ruby-forum.com/t/creating-and-passing-a-block-in-a-c-extension/112162/3 "2007-08-16T07:01:05Z")

</div>

2007/8/15, Tim H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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?

---

<div class="post-metadata">

**Author:** ![Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/c37758/32.png) [@Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/u/Gerardo_SSGSSS_mez)\
**Post date:** [August 16, 2007, 2:56pm UTC](https://www.ruby-forum.com/t/creating-and-passing-a-block-in-a-c-extension/112162/4 "2007-08-16T14:56:01Z")

</div>

On Aug 16, 1:00 am, “Gerardo S. Gómez Garrido”  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.

---

<div class="post-metadata">

**Author:** ![Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/c37758/32.png) [@Gerardo\_SSGSSS\_mez](https://www.ruby-forum.com/u/Gerardo_SSGSSS_mez)\
**Post date:** [August 16, 2007, 3:06pm UTC](https://www.ruby-forum.com/t/creating-and-passing-a-block-in-a-c-extension/112162/5 "2007-08-16T15:06:02Z")

</div>

On Aug 16, 1:00 am, “Gerardo S. Gómez Garrido”  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thank you Tim, that function is what I was looking for.  
> Gerardo S.  
> 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’.
