C和Lua - 将本机对象实例传递给本机Lua函数

时间:2016-02-09 11:03:52

标签: c object static lua

传递给Lua以便Lua可以调用本机函数的C函数是静态函数,因此与对象实例无关。

在我的应用程序中,我有多个会话。每个会话都在自己的线程上运行,有自己的数据和自己的脚本,会话N的脚本必须能够访问该会话N的数据。

问题是,当你从Lua注册一个可以调用的本机C函数时,我无法传递会话对象的实例,使其在静态Lua函数中可用。

一种可能性是将会话实例存储到静态变量中,该静态变量可以从静态C函数(从Lua调用)调用,但这看起来很脏并且需要同步,这可能导致某些脚本挂起。 / p>

第二种可能性是创建一个Lua对象来表示会话并在其上调用成员方法,以便在我的C函数中,我有办法访问表示会话的Lua对象(“t​​his”)和检索此对象表示的实际本机会话实例。但我不知道该怎么做。

有没有办法在Lua中创建表示本机对象实例的Lua对象,以便本机Lua函数可以访问该本机对象实例?

3 个答案:

答案 0 :(得分:2)

当您使用Lua注册C函数时,您可以将其他值存储为所谓的“upvalues”。然后,C函数可以在调用时检索这些值:

// ...
// 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)

在静态C函数中,您可以访问实例数据,如下所示:

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;
}

答案 1 :(得分:0)

由于每个会话都有自己的主题,为什么不将它们链接在一起呢? 每当调用函数时,从当前线程获取会话。

您可能需要查看有关userdata的手册。

答案 2 :(得分:0)

因为"每个会话都在自己的线程上运行"您只需将会话数据保存为静态thread-local

最好是按userdata传输会话数据,并为metatable绑定相关功能,并且不要依赖静态内容。

作为最后一种选择,让我们结合起来:将会话数据保存为userdata / pointer Lua-state-local

在所有情况下,您都必须关心类实例的破坏,因为用户数据以C风格释放,与线程数据相同。