使用lua脚本配置C++程序窗口大小:
lua脚本内容:
-- lua配置文件,配置窗口大小
width=200
height=300
C++源码:
// LuaConfig.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <windows.h>
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
#pragma comment(lib,"..\\lib\\lua51.lib")
// 正数为栈底,负数为栈顶
// 打印出错信息,关闭lua_State,并退出程序
void error(lua_State* L,const char* fmt,...)
{
va_list argp;
va_start(argp,fmt);
vfprintf(stderr, fmt, argp);
lua_close(L);
exit(EXIT_FAILURE);
}
//
void load(lua_State *L, const char *fname, int *w, int *h)
{
int err = luaL_loadfile(L,fname) || // 加载文件
lua_pcall(L,0,0,0); // 调用文件
if(err)
{
error(L,"cant not run config. file:%s\n",lua_tostring(L,-1)); // 从栈中取出错误信息
}
else
{
lua_getglobal(L,"width"); // 获取全局变量值,并压入栈中
lua_getglobal(L,"height"); // 获取全局变量的值,并压入栈中
/*
height
width
*/
if(!lua_isnumber(L,-2)) // 判断从栈顶开始的第2个元素,即height是不是数字
error(L,"\'width\' should be a number\n");
*w = lua_tonumber(L,-2);
if(!lua_isnumber(L,-1))
error(L,"\'height\' should be a number\n");
*h = lua_tonumber(L,-1);
}
}
// 获取配置文件路径
char *getCfgPath()
{
char pchAppPath[MAX_PATH] = { 0 };
GetModuleFileNameA(NULL,pchAppPath,MAX_PATH);
char* pchAppName = strrchr(pchAppPath,'\\');
char pchCfgPath[MAX_PATH] = { 0 };
int sz = sizeof(char)*(strlen(pchAppPath)-strlen(pchAppName));
memcpy(pchCfgPath,pchAppPath,sz);
const char cfgname[] = "\\cfg\\cfg.lua";
int len = strlen(pchCfgPath)+strlen(cfgname)+1;
strcat_s(pchCfgPath,len,cfgname);
return pchCfgPath;
}
int _tmain(int argc, _TCHAR* argv[])
{
int w = 0;
int h = 0;
lua_State* L = luaL_newstate();
load(L,getCfgPath(),&w,&h);
printf("w:%d h:%d\n",w,h);
char pchSetCmd[128] = { 0 };
sprintf_s(pchSetCmd,128,"mode con cols=%d lines=%d",w,h);
system(pchSetCmd);
lua_close(L);
return 0;
}
对于这类简单的任务来说,用一个简单的配置文件记录这两个值就足够了,这比lua更易于使用。
但这里使用lua可以带来一些优势,lua会处理所有的语法细节和语法错误,包括配置文件中的一
些注释,其次用户可以实现一些更复杂的配置逻辑,比如说可以使用脚本来提示用户某些信息或
者查询某个环境变量。
用环境变量的值来配置窗口大小
lua脚本内容:
-- lua配置文件,配置窗口大小
if os.getenv("DISPLAY")==":0.0" then
width=60
height=30
else
width=30
height=60
end
print(width,height)
C++源码:
// LuaConfig.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <windows.h>
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
#pragma comment(lib,"..\\lib\\lua51.lib")
// 正数为栈底,负数为栈顶
// 打印出错信息,关闭lua_State,并退出程序
void error(lua_State* L,const char* fmt,...)
{
va_list argp;
va_start(argp,fmt);
vfprintf(stderr, fmt, argp);
lua_close(L);
exit(EXIT_FAILURE);
}
//
void load(lua_State *L, const char *fname, int *w, int *h)
{
int err = luaL_loadfile(L,fname); // 加载文件
err = !err && lua_pcall(L,0,0,0); // 调用文件
if(err)
{
error(L,"cant not run config file:%s\n",lua_tostring(L,-1)); // 从栈中取出错误信息
}
else
{
lua_getglobal(L,"width"); // 获取全局变量值,并压入栈中
lua_getglobal(L,"height"); // 获取全局变量的值,并压入栈中
/*
height
width
*/
if(!lua_isnumber(L,-2)) // 判断从栈顶开始的第2个元素,即height是不是数字
error(L,"\'width\' should be a number\n");
*w = lua_tonumber(L,-2);
if(!lua_isnumber(L,-1))
error(L,"\'height\' should be a number\n");
*h = lua_tonumber(L,-1);
}
}
// 获取配置文件路径
char *getCfgPath()
{
char pchAppPath[MAX_PATH] = { 0 };
GetModuleFileNameA(NULL,pchAppPath,MAX_PATH);
char* pchAppName = strrchr(pchAppPath,'\\');
char pchCfgPath[MAX_PATH] = { 0 };
int sz = sizeof(char)*(strlen(pchAppPath)-strlen(pchAppName));
memcpy(pchCfgPath,pchAppPath,sz);
const char cfgname[] = "\\cfg\\cfg2.lua";
int len = strlen(pchCfgPath)+strlen(cfgname)+1;
strcat_s(pchCfgPath,len,cfgname);
return pchCfgPath;
}
int _tmain(int argc, _TCHAR* argv[])
{
int w = 0, h = 0;
lua_State* L = luaL_newstate();
luaL_openlibs(L); // 需要打开库,才能执行lua文件中的库函数
load(L,getCfgPath(),&w,&h);
printf("w:%d h:%d\n",w,h);
char pchSetCmd[128] = { 0 };
sprintf_s(pchSetCmd,128,"mode con cols=%d lines=%d",w,h);
// 通过命令行设置窗口大小
system(pchSetCmd);
lua_close(L);
system("pause");
return 0;
}