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___)