Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: No Subject: Embed in C application

11 views
Skip to first unread message

Jesse van den Kieboom

unread,
Jul 14, 2004, 8:39:35 AM7/14/04
to
On Wed, 2004-07-14 at 14:33, Jesse van den Kieboom wrote:
> Hi,
>
> I'm working on a small scripting support for a C application I wrote.
> The idea is to let users execute script functions they define and
> register. To control things in the main application there are two
> classes defined with some methods (all in C). Actually it works, I scan
> the scripts directory for scripts, load them into ruby with rb_require
> and call register_functions for that file. The register_functions will
> call a global defined function register_function (which is defined in C)
> to register a method.
>
> Now having done this, when the user wants to execute a certain script
> function I rb_require the appropriate script file and call the function.
> This works for now, but there are things I'm doing wrong.
>
> For instance. Its not nessescary for ruby to stay alive after a script
> is executed. I'm willing to create a Ruby 'world' every time a script
> has to run because scripts are just add-on, small and non time
> consuming. Now I call ruby_init every time a script needs to be executed
> and ruby_finalize after it executes. Problem is that ruby doesn't get
> cleaned. All code stays and I rather would not have this. I could try to
> fork the process and call ruby from within the child but I don't know
> what will happen with the callback functions for the two classes I
> created in C. Am I thinking in the wrong direction here or should there
> be something like ruby_clear?
>
> The second problem is that it works now. It actually does, but I guess
> it isn't the best way to do things. Well thats not the problem, the
> problem is that whenever I call puts or print to write something to
> stdout my application crashes (SEGVT) on rb_func_undef_alloc (or
> something like that). Could this be caused by using threads?
>
> Jesse

Sorry for the no subject... I hope this is better

Jesse

Jesse van den Kieboom

unread,
Jul 14, 2004, 8:56:22 AM7/14/04
to
On Wed, 2004-07-14 at 14:41, ts wrote:
> >>>>> "J" == Jesse van den Kieboom <trop...@orcaweb.cjb.net> writes:
>
> J> and ruby_finalize after it executes. Problem is that ruby doesn't get
> J> cleaned. All code stays and I rather would not have this. I could try to
> J> fork the process and call ruby from within the child but I don't know
> J> what will happen with the callback functions for the two classes I
> J> created in C. Am I thinking in the wrong direction here or should there
> J> be something like ruby_clear?
>
> Why you don't load the script in an anonymous module ?

Hmm, I don't even know what an anonymous module is :)

> J> The second problem is that it works now. It actually does, but I guess
> J> it isn't the best way to do things. Well thats not the problem, the
> J> problem is that whenever I call puts or print to write something to
> J> stdout my application crashes (SEGVT) on rb_func_undef_alloc (or
> J> something like that). Could this be caused by using threads?
>
> Do you ruby threads or system threads ?
>

System threads. I don't use threading myself but GTK+ (or pango, I'm not
sure) seems to thread.

ts

unread,
Jul 14, 2004, 9:04:09 AM7/14/04
to
>>>>> "J" == Jesse van den Kieboom <trop...@orcaweb.cjb.net> writes:

J> Hmm, I don't even know what an anonymous module is :)

See

rb_load_protect(VALUE name, int wrap, int *state)

if `wrap' is true, ruby will create an anonymous module and will load the
script in it. For example

svg% cat b.rb
#!/usr/bin/ruby
def tt
puts "tt"
end
svg%

svg% ruby -e 'load("b.rb"); tt'
tt
svg%

now in an anonymous module

svg% ruby -e 'load("b.rb", true); tt'
-e:1: undefined local variable or method `tt' for main:Object (NameError)
svg%

J> System threads. I don't use threading myself but GTK+ (or pango, I'm not
J> sure) seems to thread.

ruby don't really like system threads : try to avoid it if you can


Guy Decoux

Jesse van den Kieboom

unread,
Jul 14, 2004, 9:25:27 AM7/14/04
to
Okay, I understand the idea now. Problem is that I register two global
objects (from within C) in the Ruby environment. The scripts can use
these objects to do things in the main application and if I execute the
scripts in an anonymous module these objects wouldn't be know to the
script right? But maybe I can just load the file instead of requiring
it. The problem then is that when I load a script file it just executes
and I'm not able to just call a function in the script.

> J> System threads. I don't use threading myself but GTK+ (or pango, I'm not
> J> sure) seems to thread.
>
> ruby don't really like system threads : try to avoid it if you can

Well, I'll try to get them out then, but I'm not sure this can be done.

Jesse

CT

unread,
Jul 14, 2004, 9:30:07 AM7/14/04
to

ts

unread,
Jul 14, 2004, 9:32:26 AM7/14/04
to
>>>>> "J" == Jesse van den Kieboom <trop...@orcaweb.cjb.net> writes:

J> script right? But maybe I can just load the file instead of requiring
J> it. The problem then is that when I load a script file it just executes
J> and I'm not able to just call a function in the script.

The problem is not that you _can_ load the file, you *must* load it
because ruby lost all definitions after the load


Guy Decoux


Jesse van den Kieboom

unread,
Jul 14, 2004, 9:54:41 AM7/14/04
to
> The problem is not that you _can_ load the file, you *must* load it
> because ruby lost all definitions after the load

Okay, I might get it know. So if I'm understanding this all well then
after each load all previous memory, definitions, classes, all of it is
lost and I can begin clean? This is indeed just what I need.

The problem I have know is that I used to call this from C to let the
script register its functions:

rb_funcall(rb_mKernel, rb_intern("register_functions"), 0);

This worked okay when I rb_required the file. But now that I'm using
rb_load_file this fails. I suppose the register_functions from the
loaded file is not sitting in the rb_mKernel module than?:

[15:43:15] # script_register_functions: registering functions in
/home/jesse/.gnome2/gnoemoe/scripts/run.rb
[15:43:15] # script_error: Error while executing Ruby code: undefined
method `register_functions' for Kernel:Module
[15:43:15] # script_error: Ruby backtrace:
[15:43:15] # script_error: from
/home/jesse/.gnome2/gnoemoe/scripts/run.rb:39

What should I specify for 'module' in the rb_funcall?

Jesse

ts

unread,
Jul 14, 2004, 10:04:13 AM7/14/04
to
>>>>> "J" == Jesse van den Kieboom <trop...@orcaweb.cjb.net> writes:

J> This worked okay when I rb_required the file. But now that I'm using
J> rb_load_file this fails. I suppose the register_functions from the
J> loaded file is not sitting in the rb_mKernel module than?:

The loaded file need to call the register_functions, i.e. rather than
define a register_function the file must call any method that it want

J> What should I specify for 'module' in the rb_funcall?

You can't specify a module : the module don't exist after the load this is
why ruby lost the definitions.


Guy Decoux


Jesse van den Kieboom

unread,
Jul 14, 2004, 10:16:16 AM7/14/04
to
> The loaded file need to call the register_functions, i.e. rather than
> define a register_function the file must call any method that it want

Now I'm really confused. I can't call any functions that sit in the
loaded file. I can't define functions from within C that the ruby script
I load can call. What CAN I do then. I need to let my C application know
what methods there are. Every method registered is a little script. And
I need to execute these methods from my C application.

> You can't specify a module : the module don't exist after the load this is
> why ruby lost the definitions.

So how to call a function from the loaded file...

Jesse

ts

unread,
Jul 14, 2004, 10:28:05 AM7/14/04
to
>>>>> "J" == Jesse van den Kieboom <trop...@orcaweb.cjb.net> writes:

J> Now I'm really confused. I can't call any functions that sit in the
J> loaded file.

yes,

J> I can't define functions from within C that the ruby script
J> I load can call.

no,

svg% cat b.rb
#!/usr/bin/ruby
def tt

A::tt()
end

tt
svg%

svg% cat x.rb
#!/usr/bin/ruby

module A
module_function
def tt
puts "A::tt"
end
end

load("b.rb", true)
svg%

svg% x.rb
A::tt
svg%

J> So how to call a function from the loaded file...

submit a RCR ? :-)


Guy Decoux


Jesse van den Kieboom

unread,
Jul 14, 2004, 11:03:40 AM7/14/04
to

> J> So how to call a function from the loaded file...

Funny thing, cause I got it working now. What I do is I load the script
file using rb_load_file. Then I call ruby_exec. After that I start
defining the classes and global objects/functions the scripts can use.

And with eval_string I can call the functions defined in the script
(such as register_functions and the registered functions themselfs :))

So I hope this is a good way to do this.

Jesse

ts

unread,
Jul 14, 2004, 11:12:18 AM7/14/04
to
>>>>> "J" == Jesse van den Kieboom <trop...@orcaweb.cjb.net> writes:

J> So I hope this is a good way to do this.

Look in eval.c how is called rb_load_file()


Guy Decoux


Jesse van den Kieboom

unread,
Jul 14, 2004, 11:35:46 AM7/14/04
to
> Look in eval.c how is called rb_load_file()

I don'treally get your point... But I'm using rb_load now, and its still
working :)

Jesse

Ara.T.Howard

unread,
Jul 14, 2004, 11:33:37 AM7/14/04
to
On Wed, 14 Jul 2004, Jesse van den Kieboom wrote:

> So how to call a function from the loaded file...

can't you do something evil like this?

~ > cat a.rb
def user_method
p 42
end

~ > cat b.rb
class Wrapped
class << self
module_eval(IO.read('a.rb'))
end
end
Wrapped.user_method

~ > ruby b.rb
42


b.rb is obviously the C bit.


-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it.
| --Dogen
===============================================================================

ts

unread,
Jul 14, 2004, 11:41:57 AM7/14/04
to
>>>>> "J" == Jesse van den Kieboom <trop...@orcaweb.cjb.net> writes:

J> I don'treally get your point... But I'm using rb_load now, and its still
J> working :)

Look at rb_load_protect() and you don't need ruby_exec() if you use
rb_load()


Guy Decoux


Jesse van den Kieboom

unread,
Jul 14, 2004, 12:09:00 PM7/14/04
to
> Look at rb_load_protect() and you don't need ruby_exec() if you use
> rb_load()

Hmm, rb_load() SEGV's my application. rb_load_file without ruby_exec
will not register functions and do the things I want it to do.
rb_load_file and then ruby_exec will do, so I'm sticking to this.

Jesse

ts

unread,
Jul 14, 2004, 12:19:46 PM7/14/04
to
>>>>> "J" == Jesse van den Kieboom <trop...@orcaweb.cjb.net> writes:

J> rb_load_file and then ruby_exec will do, so I'm sticking to this.

rb_load_file + ruby_exec is similar to rb_load *except* that many things,
that ruby need, are not done.

See the source of rb_load() (in this function eval_node(self, node) is
similar to your call to ruby_exec())


Guy Decoux


Lennon Day-Reynolds

unread,
Jul 14, 2004, 12:45:01 PM7/14/04
to
On Wed, 14 Jul 2004 21:56:22 +0900, Jesse van den Kieboom
<trop...@orcaweb.cjb.net> wrote:
[...]

> > Do you ruby threads or system threads ?
> >
>
> System threads. I don't use threading myself but GTK+ (or pango, I'm not
> sure) seems to thread.

GTK+ and Pango may be compiled with native thread *support*, but they
(and most Glib-based toolkits) are single-threaded event-driven APIs.
If you're having reentrancy problems, you could try recompiling GTK+
(and its dependencies, Glib, ATK, and Pango) with thread support
disabled.

Lennon


Lyle Johnson

unread,
Jul 14, 2004, 1:52:22 PM7/14/04
to
On Wed, 14 Jul 2004 22:30:07 +0900, CT <deme...@gmail.com> wrote:
> http://slashdot.org/comments.pl?sid=114402&cid=9693123

I like Paul's follow up: "Give ruby a try, but don't expect it to
solve all your problems. It will not make breakfast for you in bed or
greet you with a kiss." ;)


Sean O'Dell

unread,
Jul 14, 2004, 2:13:44 PM7/14/04
to
On Wednesday 14 July 2004 06:30, CT wrote:
> http://slashdot.org/comments.pl?sid=114402&cid=9693123

The article makes excellent use of the word "arbitrary" too!

Sean O'Dell


Jesse van den Kieboom

unread,
Jul 14, 2004, 2:18:27 PM7/14/04
to

I don't think this is an option as I'm developing this for debian and it
uses the debian packages. I looked a bit further and maybe its nog GTK+
or Pango. My guess is it has to do with Gnome (or bonobo). But it seems
to work for now. Maybe I'll look into it later.

Jesse

Hal Fulton

unread,
Jul 14, 2004, 2:36:01 PM7/14/04
to

Hey, speak for yourself...

Hal


Bill Kelly

unread,
Jul 14, 2004, 2:54:07 PM7/14/04
to
Hi,

I'm beginning development of an embedded ruby application,
where I want to run ruby in a separate system thread
(not the main thread), and run an OpenGL renderer (C/C++)
in the main thread.

However I plan to never have the main thread call the ruby
interpreter directly, or vice-versa. The ruby thread and
the renderer thread will communicate via a command queue
data structure, with appropriate access synchronization.
And data owned by the ruby garbage collector will never
be seen by other threads.

What I'm wondering is, does this sound like a fairly trouble-
free approach? Or am I still stepping into dangerous
territory here? I'm hoping that by keeping the ruby thread
completely separate from the other thread(s) (except for
communication through the queueing mechanism) that I should
be safe from thread-related issues with the ruby interpreter.

However, if what I'm attempting is already known to be
fraught with problems, I'd definitely like to know! :)

Thanks for any insight and advice.

Regards,

Bill


Lennon Day-Reynolds

unread,
Jul 14, 2004, 2:57:32 PM7/14/04
to
And this is exactly the kind of thing that makes non-coders think
we're all in love with our computers...which many of us may be, but
it's probably best to keep the evidence out of the wrong hands, (i.e.,
wives, girlfriends, etc.) though.

Lennon


Lennon Day-Reynolds

unread,
Jul 14, 2004, 3:17:20 PM7/14/04
to
Bill,

Isolating the Ruby runtime in a single thread should protect most of
the runtime's internal data structures from synchronization problems,
but I don't think that the core is implemented with an eye towards
cooperating with other threads on things like signals.

If you're only allowing access to the Ruby runtime from a single
thread anyway, you might be better off just forking a child process
that handles the Ruby scripting, and having the two communicate via
some sort of RPC.

Lennon


Joel VanderWerf

unread,
Jul 15, 2004, 1:15:07 AM7/15/04
to
Jesse van den Kieboom wrote:

I'm not sure I've followed the discussion, but this is something I use
to load (or require) a script and get an actual object (a module, in
fact) that has the methods (and constants) defined in the script:

http://redshift.sourceforge.net/script/

The basic idea is just "module_eval(IO.read(file))", but there's some
convenience stuff around that.


0 new messages