1
votes

C functions that are passed to Lua to so that Lua can call native functions are static functions and thus not related to an object instance.

In my application, I have multiple sessions. Each session runs on its own thread, has its own data and its own scripts, and a script of the session N must be able to access the data of that session N.

The problem is that when you register a native C function to be callable from Lua, I can't pass the instance of the session object to make it available in the static Lua function.

One possibility could to be store the instance of the session into a static variable that can be called from the static C function (called from Lua), but this looks dirty and would require synchronization that could cause some scripts to hang.

A second possibility might be to create an Lua object that represents the session and call member methods on it so that, in my C function, I would have a way to access the Lua object representing the session ("this") and retreive the actual native session instance represented by this object. But I have no idea how to do that.

Is there a way to create Lua objects representing native object instances in Lua so that native Lua functions would have access to that native object instance ?

3
Just a quick tip: "Lua" is a name, not an acronym. That's why it's written "Lua", not "LUA" ;) For more info, see lua.org/about.html#name :) - Henrik Ilgen

3 Answers

2
votes

When you register a C function with Lua, you can store additional values as so-called "upvalues". The C function can then retrieve those values when it's called:

// ...
// push session instance pointer
lua_pushlightuserdata( L, (void*)get_current_session() );
// create a closure with one upvalue
lua_pushcclosure( L, my_static_C_function, 1 );
// ... (the resulting Lua function is at the stack top now)

In your static C function you access the instance data like this:

static int my_static_C_function( lua_State* L ) {
  session_t* instance = (session_t*)lua_touserdata( L, lua_upvalueindex( 1 ) );
  instance->do_something();
  return 0;
}
0
votes

Since each session has its own thread, why don't you link them together? Whenever your function is called, get the session from the current thread.

You might want to take a look at the manuals about userdata.

0
votes

Since "Each session runs on its own thread" you could simply save session data as static thread-local.

Better would be to transport session data by userdata, with a metatable bound for associated functions, and don't rely on static stuff.

As last alternative, let's combine: save session data as userdata/pointer Lua-state-local.

In all cases you have to care about class instances destruction because userdata are freed in C-style, same as thread data.