LuaJIT 和 C++ - 调用 Table.Method() 在 loadstring/pcall 中不起作用
LuaJIT and C++ - call to Table.Method() does not work in loadstring/pcall
我得到了 2 个在 C++ 中注册 Lua table 和方法的函数:
void LuaScriptInterface::registerTable(const std::string& tableName)
{
// _G[tableName] = {}
lua_newtable(luaState);
lua_setglobal(luaState, tableName.c_str());
}
void LuaScriptInterface::registerMethod(const std::string& globalName, const std::string& methodName, lua_CFunction func)
{
// globalName.methodName = func
lua_getglobal(luaState, globalName.c_str());
lua_pushcfunction(luaState, func);
lua_setfield(luaState, -2, methodName.c_str());
// pop globalName
lua_pop(luaState, 1);
}
它注册了一些方法:
registerTable("Game");
// Game.getHouses()
registerMethod("Game", "getHouses", LuaScriptInterface::luaGameGetHouses);
然后我打电话给Lua:
local param = "print( Game.getHouses() )"
pcall(loadstring(param))
我遇到了 param 的问题。调用和结果:
1. print(Game.getHouses())
2. print(Game['getHouses']())
3. print( Game.getHouses() ) -- added spaces
4. print( Game['getHouses']() ) -- added spaces
5. local var = Game.getHouses() print(#var)
6. local var = Game['getHouses']() print(#var)
7. local var = #Game.getHouses() print(var)
8. local var = #Game['getHouses']() print(var)
9. local var = # Game.getHouses() print(var) -- added space
结果:
1. attempt to call a nil value
2. table: 0x4351fdd0
3. table: 0x42ce6b88
4. table: 0x426513c0
5. 1010
6. 1010
7. attempt to call a nil value
8. 1010
9. 1010
谁能告诉我一个原因,为什么它在 loadstring/pcall 中不起作用?
我能以某种方式让它在 loadstring/pcall 中工作吗?
编辑:
经过2个小时的调试。我发现,我用来与服务器通信的客户端 - 执行 LUA - 对我发送的字符串做了一些正则表达式(我仍然不知道为什么,但它与 LUA 无关) :)
您试图表达的问题是 someTable.key
给出的结果与 someTable["key"]
不同,但这不可能:
But it's so common to use string constants as keys there's a special shortcut syntax for it:
> t = {}
> t.foo = 123 -- same as t["foo"] (but not t[foo], which would use the variable foo as the key)
> = t.foo
123
> = t["foo"]
123
The shortcut syntax is only valid if the string consists of underscores, letters, and numbers, but shouldn't start with a number. (http://lua-users.org/wiki/TablesTutorial)
由于它在 loadstring
中未使用时仍然有效,我怀疑您的问题出在 Player(cid)
player:getId()
或 "player:getPosition()"
上。重要的是要注意您在两个不同的时间访问播放器。 1. 直接为 player:getId()
和 2. 虽然 loadstring / pcall
。最后一种可能性是 Player(cid)
。其中之一可能未正确初始化/声明。
我认为由于不同的测试条件,您的第二次尝试 local param = "print( #Game['getHouses']() )"
成功了。
我得到了 2 个在 C++ 中注册 Lua table 和方法的函数:
void LuaScriptInterface::registerTable(const std::string& tableName)
{
// _G[tableName] = {}
lua_newtable(luaState);
lua_setglobal(luaState, tableName.c_str());
}
void LuaScriptInterface::registerMethod(const std::string& globalName, const std::string& methodName, lua_CFunction func)
{
// globalName.methodName = func
lua_getglobal(luaState, globalName.c_str());
lua_pushcfunction(luaState, func);
lua_setfield(luaState, -2, methodName.c_str());
// pop globalName
lua_pop(luaState, 1);
}
它注册了一些方法:
registerTable("Game");
// Game.getHouses()
registerMethod("Game", "getHouses", LuaScriptInterface::luaGameGetHouses);
然后我打电话给Lua:
local param = "print( Game.getHouses() )"
pcall(loadstring(param))
我遇到了 param 的问题。调用和结果:
1. print(Game.getHouses())
2. print(Game['getHouses']())
3. print( Game.getHouses() ) -- added spaces
4. print( Game['getHouses']() ) -- added spaces
5. local var = Game.getHouses() print(#var)
6. local var = Game['getHouses']() print(#var)
7. local var = #Game.getHouses() print(var)
8. local var = #Game['getHouses']() print(var)
9. local var = # Game.getHouses() print(var) -- added space
结果:
1. attempt to call a nil value
2. table: 0x4351fdd0
3. table: 0x42ce6b88
4. table: 0x426513c0
5. 1010
6. 1010
7. attempt to call a nil value
8. 1010
9. 1010
谁能告诉我一个原因,为什么它在 loadstring/pcall 中不起作用?
我能以某种方式让它在 loadstring/pcall 中工作吗?
编辑:
经过2个小时的调试。我发现,我用来与服务器通信的客户端 - 执行 LUA - 对我发送的字符串做了一些正则表达式(我仍然不知道为什么,但它与 LUA 无关) :)
您试图表达的问题是 someTable.key
给出的结果与 someTable["key"]
不同,但这不可能:
But it's so common to use string constants as keys there's a special shortcut syntax for it:
> t = {} > t.foo = 123 -- same as t["foo"] (but not t[foo], which would use the variable foo as the key) > = t.foo 123 > = t["foo"] 123
The shortcut syntax is only valid if the string consists of underscores, letters, and numbers, but shouldn't start with a number. (http://lua-users.org/wiki/TablesTutorial)
由于它在 loadstring
中未使用时仍然有效,我怀疑您的问题出在 Player(cid)
player:getId()
或 "player:getPosition()"
上。重要的是要注意您在两个不同的时间访问播放器。 1. 直接为 player:getId()
和 2. 虽然 loadstring / pcall
。最后一种可能性是 Player(cid)
。其中之一可能未正确初始化/声明。
我认为由于不同的测试条件,您的第二次尝试 local param = "print( #Game['getHouses']() )"
成功了。