2014-05-17 25 views
3

首先我很抱歉我的英語。在C++函數中使用lua_call很多次

我的問題是關於如何在C++函數中多次使用lua_call。我有一個使用lua作爲主要語言的程序,但它接受C++插件來添加功能。我想從C++調用LUA函數,並在LUA運行時中調用該C++函數。 我想在工作時用進度編寫C++函數,然後將此進度傳遞給LUA函數,該函數負責向用戶顯示進度。

現在我有一個測試功能在LUA:

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

和C++函數:

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; 
} 

然後我用調用從LUA此功能:

Test.Test(ShowText); 

與第一個lua_call一切正常,但隨後LUA樁被清除,功能在第二次lua_call嘗試使用第一次調用的返回布爾值代替函數。

我想是這樣的:

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; 
} 

和LUA:

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

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

    return true; 
end 

注:

Dialog.Message是程序THA的功能我使用顯示一條消息。就像MessageBox(NULL,Text,Title,MB_OK);在C++中。

IRLUA_PLUGIN_CheckBoolean是一個插件SDK的函數,用於檢查參數是否爲booleand並返回它的值,否則返回錯誤。

我可以用lua_getfield(L,LUA_GLOBALSINDEX,「FunctionName」);,但不是我想要的。

有人知道該怎麼做嗎?

回答

3

你已經很好地理解了這個問題。這是你如何解決它。

在第一個示例中,lua_call從堆棧彈出該函數,因此您需要先複製該函數。此外,通過該函數返回的布爾是沒用的,所以你需要彈出或只是不問它最後一個參數設置爲0到lua_call:

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; 
} 

現在將其應用於你的第二個例子:

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; 
} 

(我有固定的幾個其他問題與您的代碼:通過第二個數字大概應該是total,不j,你不希望使用continue作爲變量名...)

+0

感謝所有;) 我會做一些測試,但應該工作。你是對的,我想再次傳遞總數j,並繼續作爲變量......太糟糕了。再次感謝!! –