C和Lua - 将原生对象实例传递给原生Lua函数
传递给Lua以便Lua可以调用原生函数的C函数是静态函数,因此不涉及对象实例。C和Lua - 将原生对象实例传递给原生Lua函数
在我的应用程序中,我有多个会话。每个会话都在自己的线程上运行,拥有自己的数据和自己的脚本,并且会话N的脚本必须能够访问该会话的数据N.
问题是,当您注册本机C函数可以从Lua调用,我无法传递会话对象的实例以使其在静态Lua函数中可用。
一种可能性是可以将会话实例存储到静态变量中,该静态变量可以从静态C函数中调用(从Lua调用),但这看起来很脏并且需要可能会导致某些脚本挂起的同步。
第二种可能性可能是创建一个代表会话的Lua对象,并调用它的成员方法,这样在我的C函数中,我就可以访问代表会话的Lua对象(“this”)并检索由此对象表示的实际本地会话实例。但我不知道该怎么做。
有没有办法在Lua中创建表示本地对象实例的Lua对象,以便本地Lua函数可以访问该本地对象实例?
由于“每个会话都在自己的线程上运行”,因此您可以简单地将会话数据保存为静态thread-local。
通过userdata传输会话数据会更好,metatable绑定相关的函数,并且不依赖于静态内容。
作为最后的选择,让我们结合:将会话数据保存为用户数据/指针Lua-state-local。
在所有情况下,您必须关心类实例的破坏,因为userdata以C风格释放,与线程数据相同。
感谢您的帮助。我会尝试基于此做一些事情,并在文档中找到更多信息。此外,我不能使用线程本地,因为我使用C++作为Windows CE和Android的通用代码库,并且我无法使用C++ 11,因为我无法使用比2008更新版本的Visual Studio。 – Virus721
当您使用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;
}
只是一个快速提示:“Lua的”是出了名,不是首字母缩略词。这就是为什么它被写成“Lua”,而不是“LUA”;)有关更多信息,请参阅http://www.lua.org/about.html#name :) –