简体   繁体   中英

Using lua_call a lot of times in c++ function

first of all I'm sorry for my english.

My question is about how to use lua_call more than one time in C++ function. I have a program that uses lua as primary language, but it accept c++ plugins to add functionalities. I want to call a LUA function from c++, and call that c++ function in LUA Runtime. I want to write a c++ function with a progress while is working, then pass this progress to a LUA function which is responsible to show that progress to user.

For now I've a test function in LUA:

function ShowText(text)
    Dialog.Message("Hi", text);
    return true;
end

and a c++ function:

static int Test(lua_State *L){
    lua_pushstring(L, "Hi There");
    lua_call(L, 1, 1);

    lua_pushstring(L, "Again");
    lua_call(L, 1, 1); 

    return 0;
}

Then i call this function from LUA using:

Test.Test(ShowText);

All works fine with the first lua_call but then the LUA pile is cleared, function dissapear and the second lua_call try to use the return boolean of first call instead function.

i want something like this:

static int Test(lua_State *L){
    int total = 10;

    for (int j; j<total; j++){
        lua_pushnumber(L, j);
        lua_pushnumber(L, j);
        lua_call(L, 2, 1);
        bool continue = IRLUA_PLUGIN_CheckBoolean(L, -1);
        lua_pop(L, 1); //Delete the last boolean

        if (continue == false){
            break;
        }
    } 

    return 0;
}

and in LUA:

function ShowProgress(actual, final)
    local percent = (actual/final)*100;

    Dialog.Message("Working", "I'm in "..actual.." from "..final.." ("..percent.."%)");

    return true;
end

NOTES:

Dialog.Message is a function of the program tha i'm using to show a message. Is like MessageBox(NULL, Text, Title, MB_OK); in c++.

IRLUA_PLUGIN_CheckBoolean is a function of plugin SDK that check if argument is booleand and return its value, or return an error if not.

I can do it with lua_getfield(L, LUA_GLOBALSINDEX , "FunctionName"); , but is not what i want.

Someone knows how to do it?

You have understood the problem well. Here is how you fix it.

In your first example, lua_call pops the function from the stack so you need to duplicate it first. Also, the boolean returned by the function is useless, so you need to pop it or just not ask it to lua_call by setting the last argument to 0:

static int Test(lua_State *L) {

    lua_pushvalue(L, 1); /* duplicate function */

    lua_pushstring(L, "Hi There");
    lua_call(L, 1, 0);

    lua_pushstring(L, "Again");
    lua_call(L, 1, 0); 

    return 0;
}

Now applying that to your second example:

static int Test(lua_State *L) {
    int total = 10;

    for (int j = 0; j<total; j++) {
        lua_pushvalue(L, 1); /* duplicate function */
        lua_pushnumber(L, j);
        lua_pushnumber(L, total);
        lua_call(L, 2, 1);
        bool keep_going = IRLUA_PLUGIN_CheckBoolean(L, -1);
        lua_pop(L, 1); /* pop the boolean */

        if (keep_going == false) {
            break;
        }
    }

    return 0;
}

(I have fixed a few other issues with your code: the second number passed should probably be total , not j , you don't want to use continue as a variable name...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM