Hi
Thanks, i'ts really the 'global' versus 'local' problem (rookie error
;-)...
In fact it is the 'global' scope of the memory where 'temp' is what
counts. By declaring 'static VALUE temp;' or 'VALUE temp;' as global,
outside of the function, the problem disapears.
I examined carefully the code in the Ruby's variable.c file. There are the
following functions:
'rb_global_entry' is the function that creates -- i.e., ** allocs ** -- the
global memory for a new global variable;
'rb_define_variable' --> gets a global_id ID value and calls
'rb_global_entry';
'rb_gv_set' --> calls 'rb_global_entry' and 'rb_gvar_set' to set the
variable.
The function 'rb_global_entry' is the key for creating global vars.
It sees if the variable already exists: if it exists
it returns a pointer to it; if not, allocates memory for a new variable
(structures global_variable
and global_entry) and returns a pointer to global_entry.
The problem with my code, as Kent Dahl and Guy Decous in another answer
pointed out,
was that I was using &temp, ** a pointer to a local value, **
in the function 'rb_define_variable("$tempor",&temp)'.
Of course temp vanishes after exiting the function.
However, 'rb_gv_set("$tempor",temp)' ** uses really temp **, not a pointer
to it, and with it there is no problem,
as Guy Decoux pointed out very well in other reply. So the following code,
with temp a local variable,
works as I intended:
...........
static VALUE newvar(int argc, VALUE *argv, VALUE self) {
VALUE temp; // ***** local var
temp = rb_ary_new();
rb_ary_push(temp, rb_float_new(3.3));
rb_gv_set("$tempor", temp); // ***** uses temp, not &temp
............
In fact there is a solution to the problem without using temp at all :-)
static VALUE newvar(int argc, VALUE *argv, VALUE self) {
rb_ary_push(rb_gv_set("$tempor", rb_ary_new()), rb_float_new(3.3));
............
which uses only ** global memory ** returned by rb_ary_push, rb_gv_set,
etc...
The key for this is that 'rb_gv_set("$varname",VALUE val )' returns VALUE
val,
which allows to reuse VALUE val in 'rb_ary_push'.
Thanks again
J. Augusto
Kent Dahl wrote:
> JosAugusto wrote:
> > ------------------------------------------------
> >
> > require 'inline' # use Inline module
> >
> > class Fake
> >
> > inline_c_raw %q[
> >
> > static VALUE newvar(int argc, VALUE *argv, VALUE self) {
> > VALUE temp;
> >
> > temp = rb_ary_new();
> > rb_ary_push(temp, rb_float_new(3.3));
> > rb_define_variable("$tempor", &temp);
> > rb_global_variable(&temp);
> ^
> This should have set of your alarm bells. Notice that you give in a
> pointer to the VALUE (i.e. the container), which has local scope and is
> gone after your C function returns.
>
> Declaring temp as:
>
> static VALUE temp;
>
> might help, but my C/C++ is rusty.
>
> HTH
>
> --
> (\[ Kent Dahl ]/)_ _~_ __[ http://www.stud.ntnu.no/~kentda/ ]___/~
> ))\_student_/(( \__d L b__/ NTNU - graduate engineering - 5. year )
> ( \__\_õüõß/__/ ) _)Industrial economics and technological management(
> \____/_öß\____/ (____engineering.discipline_=_Computer::Technology___)