Now I want to create an this Object from C and access
@@some_var
How do I do that?
I tried a day, but do not get more far than access violations
I checked Google and read the Ruby chapter in the Programming Ruby
book more than once, but did not get it. So please give me a hand
static VALUE
some_s_var(VALUE klass)
{
return rb_cv_get(klass, “@@some_var”);
}
static VALUE
some_var(VALUE self)
{
return some_s_var(CLASS_OF(self));
}
void
Init_someclass()
{
VALUE someclass = rb_const_get(rb_cObject, rb_intern(“SomeClass”));
rb_define_method(someclass, “some_var”, some_var, 0);
rb_define_singleton_method(someclass, “some_var”, some_s_var, 0);
}
This is not what I wanted ot do I just wanted to use the Ruby stuff
directly no C extension library.
Here’s what I have come up with
class T1
@@some_var = [ “String1”,
“String2”,
“String3”]
end
/* Generated header
File Name : t1.c
···
At Fri, 28 Feb 2003 18:02:53 +0900, > Friedrich Dominicus wrote:
Created : 2003-02-28 09:57:47 frido
Author : Friedrich Dominicus
Time-stamp: <>
*/
#include <ruby.h> #include <stdio.h>
int main (void){
int i;
VALUE obj;
VALUE klass;
ruby_init(); /* embed Ruby into this program! /
/ uby_script(“embed”);
rb_load_file(“t1.rb”); /
obj = rb_eval_string(“load ‘t1.rb’”);
/ question why does rb_load_file does not work? /
klass = rb_const_get(rb_cObject, rb_intern(“T1”));
/ why does this work? Well my understanding ist that I loaded
the file into the embedded ruby, after that T1 is known, so I can look
it up. The problem I now is why rb_load_file does not work the same
way */
obj = rb_cv_get(klass, “@@some_var”);
for (i = 0; i < RARRAY(obj)->len; ++i){
printf(“obj[%d] = %s\n”, i, STR2CSTR(rb_ary_entry(obj,i)));
}
return 0;
}
ruby_init_loadpath(); /* initialize search path */
rb_require("t1"); /* no need for eval */
/* question why does rb_load_file does not work? */
klass = rb_const_get(rb_cObject, rb_intern("T1"));
/* why does this work? Well my understanding ist that I loaded
the file into the embedded ruby, after that T1 is known, so I can look
it up. The problem I now is why rb_load_file does not work the same
way */
/* test if @@some_var is defined before trying to access it */
obj = rb_cv_get(klass, "@@some_var");
/* test here if obj is really an Array */
for (i = 0; i < RARRAY(obj)->len; ++i){
printf("obj[%d] = %s\n", i, STR2CSTR(rb_ary_entry(obj,i)));
}
return 0;
}
If ruby give an error, you'll have a segfault : none of your calls are
protected.
rb_cvar_get() or rb_cv_get(). The former accepts ID and name
for the latter.
Well it’s a bit different (as I found out myself short after my
posting)
Just illustrated how to use those functions. I didn’t know that
you wanted to make ruby embedded, because you didn’t write so.
ruby_init(); /* embed Ruby into this program! /
/ uby_script(“embed”);
rb_load_file(“t1.rb”); /
obj = rb_eval_string(“load ‘t1.rb’”);
/ question why does rb_load_file does not work? */
HOW doesn’t it work? Possibly, you need to call ruby_init_loadpath().
···
At Fri, 28 Feb 2003 20:23:14 +0900, Friedrich Dominicus wrote:
ruby_init_loadpath(); /* initialize search path */
rb_require("t1"); /* no need for eval */
/* question why does rb_load_file does not work? */
klass = rb_const_get(rb_cObject, rb_intern(“T1”));
/* why does this work? Well my understanding ist that I loaded
the file into the embedded ruby, after that T1 is known, so I can look
it up. The problem I now is why rb_load_file does not work the same
way */
/* test if @@some_var is defined before trying to access it */
obj = rb_cv_get(klass, “@@some_var”);
/* test here if obj is really an Array */
for (i = 0; i < RARRAY(obj)->len; ++i){
printf(“obj[%d] = %s\n”, i, STR2CSTR(rb_ary_entry(obj,i)));
}
return 0;
}
If ruby give an error, you’ll have a segfault : none of your calls are
protected.
Thanks I’ll rewrite my stuff. I just wonder how you learned the usage,
as told before I have searched a lot if messages, but did not found
something that shows this…
As said I rewrote it a bit it now looks like this (no error handling!)
/* Generated header
File Name : t1.c
···
Created : 2003-02-28 09:57:47 frido
Author : Friedrich Dominicus
Time-stamp: <>
*/
#include <ruby.h> #include <stdio.h>
int main (void){
int i;
VALUE obj;
VALUE klass;
ruby_init();
ruby_init_loadpath();
/* uby_script(“embed”);
rb_load_file(“t1.rb”); */
//obj = rb_eval_string(“load ‘t1.rb’”);
rb_require(“t1”);
klass = rb_const_get(rb_cObject, rb_intern(“T1”));
obj = rb_cv_get(klass, “@@some_var”);
for (i = 0; i < RARRAY(obj)->len; ++i){
printf(“obj[%d] = %s\n”, i, STR2CSTR(rb_ary_entry(obj,i)));
}
return 0;
}
But now the very same program under Windows (just modified to call
NtInitialize before somethint else crashes after rb_const_get
this is the source I want to use under Windows:
#include <ruby.h> #include <stdio.h>
int main (int argc, char**argv){
int i;
VALUE obj;
VALUE klass;
NtInitialize(&argc, &argv);
ruby_init();
ruby_init_loadpath();
rb_require(“t1”);
klass = rb_const_get(rb_cObject, rb_intern(“T1”));
obj = rb_cv_get(klass, “@@some_var”);
for (i = 0; i < RARRAY(obj)->len; ++i){
printf(“obj[%d] = %s\n”, i, STR2CSTR(rb_ary_entry(obj,i)));
}
return 0;
}
I can not see why it works on Linux but crashes on Windows
It really would be helpful is someone has something that simple
working and could give me hand.
int main (void){
int i;
VALUE obj;
VALUE klass;
ruby_init(); /* embed Ruby into this program! */
/* At this step you are playing a dangerous game with the GC */
what you you mean which this step ?
ruby_init? How should I know what else to set up or use?
Here a stupid example :
int main(void)
{
char i;
VALUE obj;
VALUE klass;
ruby_init();
obj = rb_str_new2("a string");
/* call some ruby functions which call the GC */
i = RSTRING(obj)->ptr[0];
/* there are many chances than the String referenced by obj
was removed by the GC, and you have a segfault when you try
to access RSTRING(obj)->ptr[0] */
return 0;
}
Thanks I'll rewrite my stuff. I just wonder how you learned the usage,
as told before I have searched a lot if messages, but did not found
something that shows this...
You have also rb_load_protect() if you want to load a file and catch the
errors
rb_load_protect(VALUE path, int wrap, int *state);
if wrap is not null, ruby make the load in an anonymous module
If ruby has an error, state will be not null.
int main (void){
int i;
VALUE obj;
VALUE klass;
ruby_init(); /* embed Ruby into this program! */
/* At this step you are playing a dangerous game with the GC */
what you you mean which this step ?
ruby_init? How should I know what else to set up or use?
Here a stupid example :
int main(void)
{
char i;
VALUE obj;
VALUE klass;
ruby_init();
obj = rb_str_new2("a string");
/* call some ruby functions which call the GC */
i = RSTRING(obj)->ptr[0];
/* there are many chances than the String referenced by obj
was removed by the GC, and you have a segfault when you try
to access RSTRING(obj)->ptr[0] */
Ok I understand that now, what do I have to do that it does not
happen?
What’s the simplest but too safe way to solve my simple problem. I
just want the C side access the Ruby side as partly pointed out here.
You have also rb_load_protect() if you want to load a file and catch the
errors
rb_load_protect(VALUE path, int wrap, int *state);
Well as I understand the docs are on Japanese. Well ahem my Japanese
is non-exitant."
as told before I have searched a lot if messages, but did not found
something that shows this…
Interfacing with Ruby is easy when you hold the whole implementation in
your head
Well, probably my head is to small? Therefor I need some examples from
the parts I’m able to keep in it.
Regards
Friedrich
···
On Fri, Feb 28, 2003 at 11:23:38PM +0900, Friedrich Dominicus wrote:
Wrap your code inside a function (with the variables declared inside)
and call it after doing ruby_init().
Explanation (probably inaccurate):
Ruby’s GC is conservative, meaning that it will look for references to
objects in C’s stack. However, the base of the stack is found when you
call ruby_init, so if there were values in a deeper stack-frame they will
be ignored.
The sequence of (pertinent) functions called is
ruby_init
Init_heap
Init_stack → gets the start of C’s stack by taking the address of an
argument and saves it for later GC runs
then at some point when marking the GC does
rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END);
that’s why it will only mark objects held in stack frames over (less
deep than) the initial one (the one ruby_init was run in).
···
On Sat, Mar 01, 2003 at 12:04:03AM +0900, Friedrich Dominicus wrote:
/* there are many chances than the String referenced by obj
was removed by the GC, and you have a segfault when you try
to access RSTRING(obj)->ptr[0] */
Ok I understand that now, what do I have to do that it does not
happen?
What’s the simplest but too safe way to solve my simple problem. I
just want the C side access the Ruby side as partly pointed out here.
Well as I understand the docs are on Japanese. Well ahem my Japanese
is non-exitant."
The point is that for most of us the sources are the only documentation when
something isn’t mentioned in the Pickaxe. BUT Guy Decoux doesn’t need docs.
as told before I have searched a lot if messages, but did not found
something that shows this…
Interfacing with Ruby is easy when you hold the whole implementation in
your head
Well, probably my head is to small? Therefor I need some examples from
the parts I’m able to keep in it.
This makes me think of matz’s talk at LL2
“we, mere mortals, are limited”
(shows horizontal line over brain-power graph)
“some even less”
(lowers the line => laughters)
What happens here is that you were asking “I wonder how you learned the
usage” to one of the persons who knows the most about Ruby’s internals
(I have the feeling he could recite the source code :).
WE are the mere mortals, HE is the Ruby-hacker god.
···
On Sat, Mar 01, 2003 at 02:05:01AM +0900, Friedrich Dominicus wrote:
obj = rb_str_new2("a string");
/* call some ruby functions which call the GC */
i = RSTRING(obj)->ptr[0];
...
}
int main(void)
{
ruby_init();
do_stuff();
}
···
On Fri, Oct 10, 2003 at 01:15:26AM +0900, Friedrich Dominicus wrote:
/* At this step you are playing a dangerous game with the GC */
what you you mean which this step ?
ruby_init? How should I know what else to set up or use?
Here a stupid example :
int main(void)
{
char i;
VALUE obj;
VALUE klass;
ruby_init();
obj = rb_str_new2("a string");
/* call some ruby functions which call the GC */
i = RSTRING(obj)->ptr[0];
/* there are many chances than the String referenced by obj
was removed by the GC, and you have a segfault when you try
to access RSTRING(obj)->ptr[0] */
Ok I understand that now, what do I have to do that it does not
happen?
What’s the simplest but too safe way to solve my simple problem. I
just want the C side access the Ruby side as partly pointed out here.
isn’t there some effort at a wiki-rdoc hackup of the ruby source? if so,
could someone point me to it? if not, let’s start it.
-a
···
On Sat, 1 Mar 2003, Mauricio [iso-8859-1] Fernández wrote:
The point is that for most of us the sources are the only documentation when
something isn’t mentioned in the Pickaxe. BUT Guy Decoux doesn’t need docs.
–
Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================
Ok I understand that now, what do I have to do that it does not
happen?
Well in my case you need to write
void tt()
{
char i;
VALUE obj;
obj = rb_str_new2("a string");
/* call some ruby functions which call the GC */
i = RSTRING(obj)->ptr[0];
}
I have another question related to this, aren’t there any functions
provided to inform the GC that a particular object should not be
collected at the moment? As shown I do not know the ins/outs from
Ruby, but I have learned about dealing with a copying GC in Eiffel an
there some features are provided to exclude a particular object from
beein moved. There this function have names with freeze or frozen in
it. Is OBJ_FREEZE supposed to do something simular?