#include "lua_runner.hpp" #include extern "C" { #include #include "errors.h" } Lua_runner::Lua_runner(const char *path) { this->L =NULL; this->L = luaL_newstate(); errno = 0;//清除老错误信息 if(this->L == NULL) errno = NAPI_LUA_STATE_ERROR; luaL_openlibs(this->L);//创建lua状态机,打开标准库 char buf[64]; if(luaL_dostring(this->L, "package.path = \";/data/storage/el2/luapkg/?/init.lua\"") != LUA_OK)//TODO 修改加载库的默认路径指向沙盒内路径 errno = NAPI_LUA_INITFAIL;//加载默认路径 if(path !=NULL) { char buf[1024]; snprintf(buf, sizeof(buf), "package.path = package.path .. \";%s\"", /* 追加风格 */ path); if(luaL_dostring(this->L,buf) != LUA_OK)//加载用户路径 errno = NAPI_LUA_INITFAIL; } this->pkg_cont = 0; } Lua_runner::~Lua_runner() { lua_close(this->L); } bool Lua_runner::check_file_exists(const char *path) { FILE* file = fopen(path, "r"); if (file) { fclose(file); return true; } return false; } bool Lua_runner::check_luastatue() { /*检查lua状态机状况*/ if(this->L == NULL) { errno = NAPI_LUA_STATE_ERROR; return false; } //分为两部分写,防止空指针访问 if(lua_status(this->L) != LUA_OK) { errno = NAPI_LUA_STATE_ERROR; return false; } return true; } lua_State *Lua_runner::get_lua_State() { return this->L; } int Lua_runner::load_lib(const char *path,const char *name) { //如果引入哈希表会导致删除包时的多次哈希查询,污染缓存。同时性能仅与数组实现相当 if(!this->check_luastatue()) { return -1; } if(!this->check_file_exists(path)) { errno = NAPI_LOAD_FILE_ERROR; return -1; } if(this->pkg_cont>=MAX_LUA_LIB) { errno = NAPI_LUALIB_LOAD_OVER_STACK; return -1; } if(luaL_loadfile(this->L,path)!=LUA_OK) { const char *ret = lua_tostring(this->L, -1); this->reslt = ret;//存储返回值 errno =NAPI_LOAD_FILE_ERROR; lua_pop(this->L,1); return -1; } this->pkgs[this->pkg_cont].ref = lua_gettop(this->L)+1; snprintf(pkgs[pkg_cont].name,128,"%s",name); this->pkg_cont++; return 0; } int Lua_runner::unload_lib(const char *name) { int sig = 0; for(int i;ipkg_cont;i++) { if(strcmp(this->pkgs[i].name,name) == 0) { sig = i; break;//查找指定的库,查到则将标志位置为库的位置 } } if(sig == -1) { errno = NAPI_UNLOADLIB_FAIL; return -1;//没有查到返回异常(尝试卸载未加载的库) } /*检查lua状态*/ if(!this->check_luastatue()) { return -1; } lua_remove(this->L,this->pkgs[sig].ref); for(int j = sig+1;jpkg_cont;j++) { this->pkgs[j-1] = this->pkgs[j];//保持数据结构 this->pkgs[j-1].ref--;//虚拟栈位置同步变化 } this->pkg_cont--; return 1; } int Lua_runner::clean()//进行新一轮调用前一定要先clean清除上个脚本执行的痕迹 { if(!this->check_luastatue()) { return -1; } luaL_dostring(this->L, "package.loaded = {}");//清空当前引用的包 for(int i = 0 ;ipkg_cont;i++) { lua_remove(this->L,this->pkgs[i].ref); } this->pkg_cont = 0; lua_settop(this->L, 0);//清空栈 return 0; } int Lua_runner::run(const char *path,const char *arg) { if(!this->check_luastatue()) { return -1; } if(path !=NULL)//加载脚本 luaL_loadfile(this->L,path); else{ this->pkg_cont--; } if(arg !=NULL)//压栈参数 lua_pushstring(this->L,arg); if(lua_type(L, -1) == LUA_TFUNCTION) { if(lua_pcall(this->L,0,1,0) !=LUA_OK)//若栈顶为函数,直接调用 { const char *ret = lua_tostring(this->L, -1); this->reslt = ret;//存储返回值 errno =NAPI_SCRIPT_ERROR; return -1; } } else { if(lua_pcall(this->L,1,1,0) !=LUA_OK)//执行 { const char *ret = lua_tostring(this->L, -1); this->reslt = ret;//存储返回值 errno =NAPI_SCRIPT_ERROR; return -1; } } if(!lua_isstring(this->L,lua_gettop(this->L))) { if(lua_gettop(this->L)<2)//后续不会再有调用 { errno = NAPI_SCRIPT_BAD_RET; return -1; } } const char *ret = lua_tostring(this->L, -1); this->reslt = ret;//存储返回值 return 0; } int Lua_runner::callfunction() { }