Lua堆栈问题

Lua堆栈问题,lua,stack,Lua,Stack,我真的无法用一个简短而描述性的标题来解释我的问题,为此我感到抱歉 < >我调用C++中的一个名为Hoo.Lead(事件,…)的Lua函数。它调用使用hook.Add(事件、唯一名称、函数)添加的所有函数 问题是,当我在钩子中调用print(…)函数时,它不会打印您希望它打印的内容,因为调用钩子的堆栈仍然存在。所以它是从这个堆栈中打印出来的。 我不能移除堆栈,因为那样我就无法从钩子中获取返回值 钩子调用如下所示: int CGame::Update(bool haveFocus, unsigned

我真的无法用一个简短而描述性的标题来解释我的问题,为此我感到抱歉

< >我调用C++中的一个名为Hoo.Lead(事件,…)的Lua函数。它调用使用hook.Add(事件、唯一名称、函数)添加的所有函数

问题是,当我在钩子中调用print(…)函数时,它不会打印您希望它打印的内容,因为调用钩子的堆栈仍然存在。所以它是从这个堆栈中打印出来的。 我不能移除堆栈,因为那样我就无法从钩子中获取返回值

钩子调用如下所示:

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所指出的,当前的形式是从堆栈中检索内容。我建议您接受自己的答案。否则这个问题会在列表中显示为“未回答”。我建议你接受自己的答案。否则,此问题在列表中显示为“未回答”。