我正在编写一个名为LuaVM的库来管理Lua脚本与我自己的项目之间的交互,使用Lua库。
我正在寻找一种方法来暴露一些“本地”协程变量。所以我可以使用相同的“变量名称”从不同的协程访问不同的值。但是你可能知道协同程序与它们的lua_State父级共享相同的全局环境,并且它们都是从同一个lua_State发出的其他协同程序。
例如,我想将thisItem
全局公开给每个协同程序,因此每个脚本(每个脚本都有自己的协程)可以调用thisItem
并获得不同的值,即使它们正在使用相同的lua_State父级并且是嵌套的。
所以我尝试了不同的方法,例如使用堆栈暴露/取消该值,但实际上没有一个是“线程”证明。
我的最后一次尝试是将全局thisItem
与metatable关联,其中__index
和/或__call
键被修改为调用函数,而函数又尝试返回正确的值。
以下是我揭露它的方式
//-- Define a callback function
int LuaVM::DEBUGFUNCTION(lua_State *L)
{
//-- Do stuff to return the right value
return 1;
}
//-- Create callback metatable in the constructor
LuaVM::LuaVM()
{
//--Init Lua
mState = luaL_newstate();
luaL_openlibs(mState);
/* etc...*/
//-- Define the callback metatable
luaL_newmetatable(mState, "ThreadLocalMT");
lua_pushstring(mState, "__call");
lua_pushcclosure(mState, DEBUGFUNCTION,0);
lua_settable(mState, -3);
}
//-- Then define the exposeInstance function
template <class C>
bool LuaVM::exposeInstance(C* _ptr, /*other stuff*/ )
{
LuaObject<C>* ret = (LuaObject<C>*)lua_newuserdata(mState, sizeof(LuaObject<C>));
ret->ptr = _ptr;
luaL_getmetatable(mState, "ThreadLocalMT");
lua_setmetatable(mState, -2);
lua_setglobal(mState,"thisItem");
/* other stuff */
return true;
}
但它并不是我想要的......(我需要调用thisItem()
而不是变量thisItem
)并且我想知道是否有办法创建一个表到存储所有值并使用较少“棘手”的解决方案返回正确的值。
我不习惯线程也不习惯Lua C-api,所以我需要你的帮助。 在多线程环境中管理此问题可能有更好的方法吗?
谢谢
答案 0 :(得分:1)
如果您使用的是Lua 5.1.x,那么您可以使用lua_setfenv
来设置协同程序的环境(如here所述)。使用具有所需全局绑定的表,并可选择使用具有__index
常用全局变量_G
的元表。 Lua 5.1参考手册章节2.9 Environments
在Lua 5.2中,事情有点复杂(对于这个用例);相关参考手册部分为2.2 – Environments and the Global Environment