文章目录
LUA库的编译
常规配置
指定输出目录
便于后期使用
修改为静态库
便于开发中的头文件引用
在共享DLL中使用MFC
便于MFC工程的开发使用
在预编译器中定义LUA_BUILD_AS_DLL
使生成的是库,而不用生成可执行文件,便于其他工程的引用
编译生成lib
├─debug
│ lualib.lib
│ lualib.pdb
│
└─release
lualib.lib
lua.lib库的使用
配置引用
添加头文件目录,库目录
添加链接器附加依赖项
初始化LUA状态机
bool LuaManager::Init(std::string fileName, std::string &desc)
{
lua_State *state = _stateMap[fileName];
if (state)
{
lua_close(state);
state = NULL;
}
//初始化lua虚拟机//
state = luaL_newstate();
if (!state)
{
desc = "LUA状态机创建失败...";
LOG(ERROR) << desc;
state = NULL;
_stateMap[fileName] = state;
return false;
}
luaopen_base(state);
luaopen_table(state);
luaopen_string(state);
luaopen_math(state);
luaopen_debug(state);
luaL_openlibs(state);
//注册函数,注册后在脚本可以调用Msg方法
lua_register(state, "Msg", TraceLua);
luaL_dofile(state, fileName.c_str());
//加载脚本//
int status = luaL_loadfile(state, fileName.c_str());
if (status)
{
const char * pErrorMsg = lua_tostring(state, -1);
desc = pErrorMsg;
LOG(ERROR) << "LUA文件加载失败..." << pErrorMsg;
//关闭虚拟机//
lua_close(state);
state = NULL;
_stateMap[fileName] = state;
return false;
}
LOG(INFO) << "LUA文件加载成功..."<< fileName;
_stateMap[fileName] = state;
return true;
}
//需要注册的函数
int LuaManager::TraceLua(lua_State * lua_state)
{
//得到栈底的第一个值
const char *s1 = luaL_checkstring(lua_state, 1);
lua_pop(lua_state, 1);
LOG(INFO) << "LUA TRACE: " << s1;
//返回值个数//
return 0;
}
执行LUA脚本中的函数
bool PlcMgr::GetLiftStatus(int entrance, opc::LiftStatus & status, string & desc)
{
lua_State *state = theHost->_luaMgr->GetLuaState(LUA_PLC_FILENAME);
if (!state)
{
return false;
}
//函数名称//
lua_getglobal(state, "get_lift_status");
//传参//
lua_pushnumber(state, entrance);
try
{
//1 代表传参的个数为1, 2代表返回值的个数为2
int iRet = lua_pcall(state, 1, 2, 0);
if (iRet)
{
const char * pErrorMsg = lua_tostring(state, -1);
LOG(ERROR) << "LUA GetLiftStatus lua_pcall失败..." << pErrorMsg;
return false;
}
//在脚本中如果return 'abc', 1,那么1在栈顶即-1,字符串在-2//
//1代表栈底,-1代表栈顶//
if (!lua_isnumber(state, -2))
{
LOG(ERROR) << "参数1需要是数值...";
return false;
}
if (!lua_isstring(state, -1))
{
LOG(ERROR) << "参数1需要是字符串...";
return false;
}
int statusInt = (int)lua_tointeger(state, -2);
desc = lua_tostring(state, -1);
}
catch (...)
{
LOG(ERROR) << "LUA SendOrderToLift失败...";
return false;
}
return false;
}
脚本展示
function get_lift_status(entrance)
Msg('asd') --即注册的函数
res, status = ReadOPC(i, PR_ENTRANCE_STATUS) --带着返回值的注册函数
if(res) then
return 0, "ComErr"
end
if(status==0) then
return status, "asd"
elseif(status==1) then
return status, "asd"
else
return 0, "dataErr"
end
end