Lua堆栈问题
我真的无法用一个简短而描述性的标题来解释我的问题,为此我感到抱歉 < >我调用C++中的一个名为Hoo.Lead(事件,…)的Lua函数。它调用使用hook.Add(事件、唯一名称、函数)添加的所有函数 问题是,当我在钩子中调用print(…)函数时,它不会打印您希望它打印的内容,因为调用钩子的堆栈仍然存在。所以它是从这个堆栈中打印出来的。 我不能移除堆栈,因为那样我就无法从钩子中获取返回值 钩子调用如下所示:Lua堆栈问题,lua,stack,Lua,Stack,我真的无法用一个简短而描述性的标题来解释我的问题,为此我感到抱歉 < >我调用C++中的一个名为Hoo.Lead(事件,…)的Lua函数。它调用使用hook.Add(事件、唯一名称、函数)添加的所有函数 问题是,当我在钩子中调用print(…)函数时,它不会打印您希望它打印的内容,因为调用钩子的堆栈仍然存在。所以它是从这个堆栈中打印出来的。 我不能移除堆栈,因为那样我就无法从钩子中获取返回值 钩子调用如下所示: int CGame::Update(bool haveFocus, unsigned
int CGame::Update(bool haveFocus, unsigned int updateFlags)
{
hook::StartCall("PreGameUpdate");
hook::PushInteger(haveFocus);
hook::PushInteger(updateFlags);
hook::CallReturn(1, 2); //Calls hook.Call("PreGameUpdate", haveFocus, updateFlags) here
//The first argument is the amount of values to return to C++
//The second argument is how many values that were pushed onto the stack (maybe I can monitor that?)
if(hook::IsBoolean(1) && hook::GetBoolean(1) == false)
return false; //skip the rest of the code if we return false in the Pre hook
hook::End();
//rest of the code in CGame::Update() here
}
我想打印下一帧,但听起来真的很糟糕,我甚至不知道该怎么做
钩子的作用
namespace hook
{
void StartCall(string hookname)
{ lua_State *L = LuaJIT::GetState();
//Remove any previous stack (just in case?)
//Stack is now: nil
lua_settop(L, 0);
//Get the "hook" global and check if it exists
//stack is now: hook
lua_getglobal(L, "hook");
if (!lua_istable(L, -1))
return;
//Get the function "Call" and check if it exists
//Stack is now: hook.Call()
lua_getfield(L, -1, "Call");
if (!lua_isfunction(L, -1))
return;
//Remove the "hook" table from the stack leaving only the Call function left
//Stack is now: Call()
lua_remove(L, 1);
//Push the hookname onto the stack
//Stack is now: Call(hookname)
lua_pushstring(L, hookname);
}
void CallReturn(int returns, int args)
{ lua_State *L = LuaJIT::GetState();
//PrintStack("PRE PCALL");
/* When printing the stack, this is the output:
===========PRE PCALL=================START
1:
function: 2116D588
2:
PreGameUpdate
3:
1.000000
4:
0.000000
===========PRE PCALL=================END
*/
//Check if the first value is a function and if the stack is valid
if (!lua_isfunction(L, 1) || lua_gettop(L) == 0)
{
PrintStack("NO FUNCTION IN STACK");
return;
}
//pcall "Call" from the stack and check if it worked
//Stack is now: pcall(Call(hookname, ...))
int status = lua_pcall(L, args + 1, returns, 0);
//Check if it errored
if(status != 0)
{
//Print to debug output if it errored
PrintStack("STACK");
Msg("PCALL ERROR[%s]: %s", lua_tostring(L, 1), lua_tostring(L, -1));
}
//PrintStack("POST PCALL");
}
void End()
{ lua_State *L = LuaJIT::GetState();
//Remove the stack again
//Stack is now: nil
lua_settop(L, 0);
}
void EndNoReturn(int args)
{
CallReturn(0, args);
End();
}
void StartCallNoPush(string hookname, int returns)
{
StartCall(hookname);
CallReturn(0, returns);
}
void CallSimple(string hookname)
{
StartCall(hookname);
CallReturn(0, 0);
End();
}
void PushBoolean(bool res)
{ lua_State *L = LuaJIT::GetState();
int test = toint(res);
lua_pushboolean(L, test);
}
bool GetBoolean(int idx)
{ lua_State *L = LuaJIT::GetState();
int res = lua_toboolean(L, idx);
lua_pop(L, 1);
return tobool(res);
}
int IsBoolean(int idx)
{ lua_State *L = LuaJIT::GetState();
int res = lua_isboolean(L, idx);
lua_pop(L, 1);
return res;
}
//The rest of the code is just like the three functions above but for different types
}
打印功能
int print(lua_State *L)
{
//PrintStack("PRINT PRE");
int n = lua_gettop(L); /* number of arguments */
int i;
lua_getglobal(L, "tostring");
for (i=1; i<=n; i++) {
const char *s;
lua_pushvalue(L, -1); /* function to be called */
lua_pushvalue(L, i); /* value to print */
lua_call(L, 1, 1);
s = lua_tostring(L, -1); /* get result */
if (s == NULL)
return luaL_error(L, LUA_QL("tostring") " must return a string to "
LUA_QL("print"));
if (i>1) CryLogAlways("\t");
CryLogAlways(s);
lua_pop(L, 1); /* pop result */
}
CryLogAlways("\n");
//PrintStack("PRINT POST");
return 0;
}
int打印(lua_State*L)
{
//打印堆栈(“打印前”);
int n=lua_gettop(L);/*参数数*/
int i;
lua_getglobal(L,“tostring”);
对于(i=1;i1)CryLogAlways(“\t”);
CryLogAlways(s);
lua_pop(L,1);/*pop结果*/
}
CryLogAlways(“\n”);
//打印堆栈(“打印后”);
返回0;
}
我没有充分利用打印功能。我从我朋友的代码中获取了它,所以它不像那些钩子函数那样被注释。当不在钩子中调用时,打印不起作用
所以print的问题是它会打印hook堆栈中的所有内容,因为它是在我移除堆栈之前调用的
我还发现推送和弹出非常混乱,因此它确实有助于注释代码,就像在hook调用函数中显示堆栈当前是什么一样
< P>我猜整个问题是C++中钩子函数的一个设计缺陷,但我真的不知道我会怎么做。< P>我在int打印的底部弹出了ToStin字符串,作为注释中提到的INTJAY,现在它的工作应该像现在一样。
很抱歉描述得不够详细。我弹出了interjay在评论中提到的int print底部堆栈的字符串,它现在正常工作
很抱歉描述得不够详细。您说过打印功能不能达到预期效果,但您从未说过预期效果。看起来它应该打印堆栈的全部内容,根据你的问题,它就是这样做的。顺便说一句,在
print
的末尾似乎缺少一个pop(堆栈上仍保留tostring
的值)。是的,我认为我的问题中缺少了一些东西:print的问题是它打印钩子堆栈中的所有内容,因为它是在我移除堆栈之前调用的。我对C++和LuaAPI非常陌生;当我完成某件事时,我应该移除堆栈吗?我在hook::End()中使用lua_settop(L,0)来删除它,通常人们使用lua_pop从末尾的堆栈中删除一个值。难道他们不应该把它全部拿走吗?我将在最后添加lua_pop,但我认为它仍然不能解决我的问题。请详细说明print()函数要实现的功能。正如用户interjay所指出的,在其当前的形式中,它正在从堆栈中检索内容。您说过打印功能不会做您期望的事情,但您从未说过您期望它做什么。看起来它应该打印堆栈的全部内容,根据你的问题,它就是这样做的。顺便说一句,在print
的末尾似乎缺少一个pop(堆栈上仍保留tostring
的值)。是的,我认为我的问题中缺少了一些东西:print的问题是它打印钩子堆栈中的所有内容,因为它是在我移除堆栈之前调用的。我对C++和LuaAPI非常陌生;当我完成某件事时,我应该移除堆栈吗?我在hook::End()中使用lua_settop(L,0)来删除它,通常人们使用lua_pop从末尾的堆栈中删除一个值。难道他们不应该把它全部拿走吗?我将在最后添加lua_pop,但我认为它仍然不能解决我的问题。请详细说明print()函数要实现的功能。正如用户interjay所指出的,当前的形式是从堆栈中检索内容。我建议您接受自己的答案。否则这个问题会在列表中显示为“未回答”。我建议你接受自己的答案。否则,此问题在列表中显示为“未回答”。