# Use a core C function not included in intern.h

**URL:** <https://www.ruby-forum.com/t/use-a-core-c-function-not-included-in-intern-h/189623>\
**Category:** Ruby\
**Created:** [June 4, 2010, 2:48am UTC](https://www.ruby-forum.com/t/use-a-core-c-function-not-included-in-intern-h/189623 "2010-06-04T02:48:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tiny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/91b2a8/32.png) [@tiny](https://www.ruby-forum.com/u/tiny)\
**Post date:** [June 4, 2010, 2:48am UTC](https://www.ruby-forum.com/t/use-a-core-c-function-not-included-in-intern-h/189623/1 "2010-06-04T02:48:08Z")

</div>

Hello.

I trying to make a function with C extension for 1.8.7 that should use  
functions defined in Ruby such as

> VALUE eval(VALUE,VALUE,VALUE,const char\*,int)  
> But functions that aren’t reflected (sorry, I don’t know how to call it  
> better r\_r) in intern.h, seems to be unusable. If I just add string  
> VALUE eval \_((VALUE,VALUE,VALUE,const char\*,int));  
> to extension source or intern.h then I get  
> symbol lookup error: /usr/lib/ruby/gems/1.8/gems/rmtools-1.0.0/lib/rmtools.so: undefined symbol: eval

So, is there a way to use such functions in the extension without  
copypasting half the eval.c (and maybe even something else) into it?

Thanks.

---

<div class="post-metadata">

**Author:** ![tiny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/91b2a8/32.png) [@tiny](https://www.ruby-forum.com/u/tiny)\
**Post date:** [June 4, 2010, 5:20pm UTC](https://www.ruby-forum.com/t/use-a-core-c-function-not-included-in-intern-h/189623/2 "2010-06-04T17:20:28Z")

</div>

On Jun 3, 2010, at 6:48 PM, Shinku Fag wrote:

> So, is there a way to use such functions in the extension without  
> copypasting half the eval.c (and maybe even something else) into it?

The “eval” method in the eval.c source file is marked as static. It  
cannot be called from outside the eval.c source file. This is a feature  
of the compiler/linker, and to the best of my knowledge there is no easy  
way around it.

If someone with more recent C experience could chime in, it would be  
appreciated. My C is a little rusty, and would love for someone to  
double check my facts.

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![tiny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/91b2a8/32.png) [@tiny](https://www.ruby-forum.com/u/tiny)\
**Post date:** [June 4, 2010, 10:49pm UTC](https://www.ruby-forum.com/t/use-a-core-c-function-not-included-in-intern-h/189623/3 "2010-06-04T22:49:28Z")

</div>

On Jun 4, 2010, at 9:19 AM, Tim P. wrote:

> > > VALUE eval \_((VALUE,VALUE,VALUE,const char\*,int));

On second thought, use the rb\_funcall method …

rb\_funcall(rb\_mKernel, rb\_intern(“eval”), … )

That should do what you are trying to accomplish.

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![tiny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/91b2a8/32.png) [@tiny](https://www.ruby-forum.com/u/tiny)\
**Post date:** [June 4, 2010, 11:24pm UTC](https://www.ruby-forum.com/t/use-a-core-c-function-not-included-in-intern-h/189623/4 "2010-06-04T23:24:50Z")

</div>

Tim P. wrote:

> On Jun 4, 2010, at 9:19 AM, Tim P. wrote:
> 
> > > > VALUE eval \_((VALUE,VALUE,VALUE,const char\*,int));
> 
> On second thought, use the rb\_funcall method …
> 
> rb\_funcall(rb\_mKernel, rb\_intern(“eval”), … )
> 
> That should do what you are trying to accomplish.
> 
> Blessings,  
> TwP

Why not directly use rb\_eval\_string?

## From the README.EXT from 1.9.1-p378:

2.2.1 Evaluate Ruby P.s in a String

The easiest way to use Ruby’s functionality from a C program is to  
evaluate the string as Ruby program. This function will do the job:

VALUE rb\_eval\_string(const char \*str)

Evaluation is done under the current context, thus current local  
variables  
of the innermost method (which is defined by Ruby) can be accessed.

Note that the evaluation can raise an exception. There is a safer  
function:

VALUE rb\_eval\_string\_protect(const char \*str, int \*state)

It returns nil when an error occur. And \*state is zero if str was  
successfully evaluated, or nonzero otherwise.

Marvin

---

<div class="post-metadata">

**Author:** ![tiny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/91b2a8/32.png) [@tiny](https://www.ruby-forum.com/u/tiny)\
**Post date:** [June 5, 2010, 8:30pm UTC](https://www.ruby-forum.com/t/use-a-core-c-function-not-included-in-intern-h/189623/5 "2010-06-05T20:30:48Z")

</div>

Tim P. wrote:

> The “eval” method in the eval.c source file is marked as static. It  
> cannot be called from outside the eval.c source file. This is a feature  
> of the compiler/linker, and to the best of my knowledge there is no easy  
> way around it.  
> Uh-huh, thanks. Now I see. Non-static functions in sources is actually  
> linkable.

> On second thought, use the rb\_funcall method …  
> Yeah, sometimes it suits for C function, though, unfortunately,  
> necessity of rb\_funcall often causes a performance penalty.

Marvin GÃ¼lker wrote:

> Why not directly use rb\_eval\_string?  
> Because it uses the ruby\_top\_self (main:Object) instead of specific  
> object in context of which we want to evaluate the string. Hence, we  
> can’t use it to evaluate an implicit method calls as ‘count("\n")’, for  
> example.
> 
> > v = eval(ruby\_top\_self, rb\_str\_new2(str), Qnil, 0, 0);

Well, I used rb\_funcall here… What I’ve tried to do is function that  
rolls the stack back to the optional frame and evaluates the src string  
in the scope of that frame.

static VALUE rb\_eval\_frame(VALUE self, VALUE src, VALUE levv)  
{  
struct FRAME \*frame\_orig = ruby\_frame;  
NODE \*node\_orig = ruby\_current\_node;  
VALUE val;  
int lev = FIX2INT(levv);

while (lev-- \> 0) {  
ruby\_frame = ruby\_frame-\>prev;  
if (!ruby\_frame) break;  
}

val = rb\_funcall(self, rb\_intern(“eval”), 1, src);  
ruby\_current\_node = node\_orig;  
ruby\_frame = frame\_orig;

return val;  
}

But I would fail anyway, because neither FRAME nor RNode nor SCOPE  
structs don’t contain references to previous scopes. Is there any way to  
get NOT current scope?
