Safe Lua invoke C++ registered function -
hey,everyone! i've c++ app embedded lua script. non-programmer edits lua script, c++ app invoke lua script , lua script invokes c++ registered function.
i use luaplus above job. question is: when script-editor makes mistakes such misspelling the parameter, c++ app crashes! can prevent happening? thanks
look @ lua_cpcall , lua_pcall. both allow protected function calls of lua in c. if return non-negative number call failed , lua stack contains error string. in cpcalls case stack otherwise unmodified. pcall you'll need @ lua_pushcclosure invoke cfunction safely.
what this: create c function of lua_* calls want, such loadfile , dofile. call function using lua_cpcall or lua_pushcclosure amd lua_pcall. allows detect if error occured in t function passed cpcall.
examples:
function hello() { string hello_ = "hello lua!"; struct c { static int call(lua_state* l) { c *p = static_cast<c*>(lua_touserdata(l,-1)); lua_pushstring(l, p->str.c_str() ); lua_getglobal(l, "print"); lua_call(l, 1, 0); //ok lua_pushstring(l, p->str.c_str() ); lua_getglobal(l, "notprint"); lua_call(l, 1, 0); //error -> longjmps return 0; //number of values on stack 'return' lua } const string& str; } p = { hello_ }; //protected call of c::call() above //with &p 1st/only element on lua stack //any errors encountered trigger longjmp out of lua , //return non-0 error code , string on stack //a return of 0 indicates success , stack unmodified //to invoke lua functions safely use lua_pcall function int res = lua_cpcall(l, &c::call, &p); if( res ) { string err = lua_tostring(l, -1); lua_pop(l, 1); //error hanlder here } //load .lua file if( (res=lual_loadfile(l, "myluafile.lua")) ) { string err = lua_tostring(l, -1); lua_pop(l, 1); //res 1 of //lua_errsyntax - lua syntax error //lua_errmem - out of memory error //lue_errfile - file not found/accessible error } //execute if( (res=lua_pcall(l,0,0,0)) ) { string err = lua_tostring(l, -1); lua_pop(l, 1); // res 1 of // lua_errrun: runtime error. // lua_errmem: memory allocation error. // lua_errerr: error while running error handler function (null in case). } // try call [a_int,b_str] = foo(1,2,"3") lua_getglobal(l,"foo"); if( lua_isfunction(l,lua_gettop(l)) ) { //foo exists lua_pushnumber(l,1); lua_pushnumber(l,2); lua_pushstring(l,"3"); lua_pushvalue(l, -4); //copy of foo() if( (res = lua_pcall(l, 3, 2, 0/*default error func*/)) ) { string err = lua_tostring(l, -1); lua_pop(l, 1); //error: see above } int a_int = (int)lua_tointeger(l,-2); string b_str = lua_tostring(l,-1); lua_pop(l,2+1); //2 returns, + copy of foo() } }
Comments
Post a Comment