Strange behaviour of addresses of lua_objects

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Strange behaviour of addresses of lua_objects

Juergen Fuhrmann
Hi, men (and women) in the moon!

Finally, I find the time  to integrate lua  into  our projects.  I  am
trying to   implement an object-oriented  interface called  olua which
(olua  means "O  lua!"  or "Objective   lua") which somehow uses ideas
from CORBA  etc.    When things  work  well  I  will post   some  more
information about this interface. 

The basic idea  is  to use  the lua  table  mechanism to create  proxy
objects  to  C objects within lua.   Addresses  of C variables  can be
registered as lua table entries, and tag  methods ensure that lua code
like "x.a=3" ends up with writing 3 to  the location of the registered
C variable.  Objects can have an entry named "invoke", which should be
a cfunction.    I this  case  they are  treated  as methods   (using a
"function" tag method), the parameter passing mechanism is the same as
for table entries.

The problem is now when  I want to use  lua objects in the same manner
as numbers and strings as parameters in methods. 

To register an object with lua I am doing essentially the following: 

typedef lua_object oluaObject; 


void oluaRegisterObject(oluaObject obj,
			char *name,
			oluaObject *val, 
			char *docstring)
{
  oluaInit();
  lua_pushobject(obj);
  lua_pushstring(name);
  lua_pushusertag(val,oluaPObjectTag);
  lua_settable();
...
}

in settable:
...
  else if (tag==oluaPObjectTag)
    {
      oluaObject *val=lua_getuserdata(entry);
 
      if (oluaIsObject(lua_getparam(3)))
	{
	  *val=lua_getparam(3);
	  if (oluaDebug) 
	    {
	      char *xoname;
	      lua_pushobject(*val);
	      lua_pushstring("_name");
	      xoname=lua_getstring(lua_gettable());
	      oluaDebug(" %s.%s=%s\n",oname,ind,xoname);
	    }
	}
      elseif 
...

in gettable:
  else if (tag==oluaPObjectTag)
    {
      oluaObject *val=lua_getuserdata(entry);
      lua_pushobject(*val);
    }
  else if
...

Now I have the problem that sometimes, when accessing the value stored
in  the location  of  val,  I get  another  object reference  than the
reference I wrote into the location from lua code. I  am aware that my
code snippets are quite  fragmentary.  My question: Is there something
tricky to take  into  account when  using  pointers to  lua_objects as
userdata in tables ? 

Overall I am very satisfied with  lua, it lets me do  what I want, and
this is up to now the only point where I 've got problems. 


Best regards

Juergen


Dr. Juergen Fuhrmann                   [hidden email]
                         Numerical Mathematics & Scientific Computing
    Weierstrass Institute for Applied Analysis and Stochastics Berlin
SOMETHING IS ROTTEN IN THIS AGE OF HOPE heiner mueller hamletmaschine


Reply | Threaded
Open this post in threaded view
|

Re: Strange behaviour of addresses of lua_objects

Roberto Ierusalimschy
> My question: Is there something
> tricky to take  into  account when  using  pointers to  lua_objects as
> userdata in tables ?

I haven't understood your point. "lua_objects" are no pointers, they are
integers, and should be handled as abstract data types in C (that is, the only
thing you can do with a lua_object is to give it back to Lua). If you have
pointers to lua_objects, they point to your own variables, since Lua never
gives you a lua_object address.

  What is a little tricky is not about pointers to lua_objects, but about
lua_objects themselves:

  Because Lua has automatic memory management and garbage collection,
  a |lua_Object| has a limited scope,
  and is only valid inside the block where it has been created.
  A C function called from Lua is a block,
  and its parameters are valid only until its end.
  It is good programming practice to convert Lua objects to C values
  as soon as they are available,
  and never to store |lua_Object|s in C global variables.

If you need a "non-volatile" reference to a Lua object in C, you must use
references (see lua_ref).

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: Lua objects and Re: Strange behaviour...

Juergen Fuhrmann
Hi, I've got the point! Thank you.

>  Roberto Ierusalimschy <[hidden email]> wrote:
>
[...]
>  
>    Because Lua has automatic memory management and garbage collection,
>    a |lua_Object| has a limited scope,
>    and is only valid inside the block where it has been created.
>    A C function called from Lua is a block,
>    and its parameters are valid only until its end.
>    It is good programming practice to convert Lua objects to C values
>    as soon as they are available,
>    and never to store |lua_Object|s in C global variables.


This was exactly the problem. I used 

typedef lua_Object oluaObject

and stored lua_Objects in C. Now I am using references to objects
and everything works well:

typedef struct {int ref;} oluaObject;
extern oluaObject oluaNull;


oluaObject oluaCreateRef(lua_Object o)
{
  oluaObject oo;
  lua_pushobject(o);
  oo.ref=lua_ref(1);
  return oo;
}

lua_Object oluaGetObject(oluaObject o)
{
  lua_Object xo;
  if (o.ref==oluaNull.ref) return LUA_NOOBJECT;
  xo=lua_getref(o.ref);
  return xo;
}

...
at the top of module initialization:
oluaNull=oluaCreateRef(lua_createtable());
...

BTW, Norman, This solves the  problem of compiler checking objects
and their references for me, otherwise I wouldn't have been able
to modify the code within one evening...


Best regards

Juergen

Dr. Juergen Fuhrmann                   [hidden email]
                         Numerical Mathematics & Scientific Computing
    Weierstrass Institute for Applied Analysis and Stochastics Berlin
SOMETHING IS ROTTEN IN THIS AGE OF HOPE heiner mueller hamletmaschine