lua_pcall與lua_call之間的區別


lua_pcall與lua_call之間的區別

定義:

void lua_call (lua_State *L, int nargs, int nresults);
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);

這兩個api的前三個參數含義一樣,只是lua_pcall在保護模式(protection mode)下調用函數。

在調用不出錯的情況下,這兩個函數的行為一模一樣,但是lua_pcall有處理調用出錯的能力,其處理方法主要取決於第四個參數 errfunc, 如果errfunc為0,則lua_pcall直接把錯誤信息通過lua_pushstring壓棧,然后返回;然后errfunc不為0,則自動調用(L, errfunc)(errmsg),errmsg表示原始出錯信息。

通常,使用errfunc輸出一些額外的出錯信息,比如stack traceback,這些信息在lua_pcall返回之后不能再得到。
lua_pcall的返回值:

  • LUA_ERRRUN: a runtime error.
  • LUA_ERRMEM: memory allocation error. For such errors, Lua does not call the error handler function.
  • LUA_ERRERR: error while running the error handler function.

下面給出了一個例子,來說明lua_pcall errfunc的工作原理:

luapcall.lua

function printmsg()
    --故意制造調用出錯
    printaa("hello world")
end

function errorhandle(str)
    return string.upper(str)
end
  • 例1,errfunc = 0
#include<iostream>
#include<string>
extern "C"{
    #include<lua.h>
    #include<lualib.h>
    #include<lauxlib.h>
}
using namespace std;

int main(){
    lua_State *L = lua_open();
    luaopen_base(L);
    luaopen_table(L);
    luaopen_string(L);

    if(luaL_loadfile(L,"luapcall.lua")){
        cout << "open file error" << endl;
        return 1;
    }
    //載入執行程序
    if(lua_pcall(L,0,0,0)){
        cout << "function call error 0" << endl;
    }

    lua_getglobal(L, "errorhandle");
    lua_getglobal(L, "printmsg");
    
    // errfunc = 0,不處理錯誤信息
    if(lua_pcall(L, 0, 0, 0)){
        cout << lua_tostring(L, -1) << endl;
        cout << "function call error 1" << endl;
    }

    lua_close(L);

    return 0;
}

執行結果:

-bash-3.00$ ./a.out
luapcall.lua:2: attempt to call global `printaa' (a nil value)
function call error 1
  • 例2, errfunc != 0
#include<iostream>
#include<string>
extern "C"{
    #include<lua.h>
    #include<lualib.h>
    #include<lauxlib.h>
}
using namespace std;

int main(){
    lua_State *L = lua_open();
    luaopen_base(L);
    luaopen_table(L);
    luaopen_string(L);

    if(luaL_loadfile(L,"luapcall.lua")){
        cout << "open file error" << endl;
        return 1;
    }
    if(lua_pcall(L,0,0,0)){
        cout << "function call error 0" << endl;
    }

    lua_getglobal(L, "errorhandle");
    lua_getglobal(L, "printmsg");
    // 使用errorhandle函數處理錯誤信息
    if(lua_pcall(L, 0, 0, -2)){
        cout << lua_tostring(L, -1) << endl;
        cout << "function call error 1" << endl;
    }

    lua_close(L);

    return 0;
}

執行結果:

-bash-3.00$ ./a.out
LUAPCALL.LUA:2: ATTEMPT TO CALL GLOBAL `PRINTAA' (A NIL VALUE)
function call error 1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM