|
|
发表于 2013-12-2 07:36:24
|
显示全部楼层
VS搭建Lua编程环境
提供两种方法:
首先不管是方法几,都要从 http://www.lua.org 下载Lua源代码,下载后解压.
方法一:
将etc文件下的luavs.bat文件复制出来到根目录,
然后打开VS的命令行工具:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg
进入Lua的根目录下,执行luavs.bat,然后在src目录下就会生成我们需要的动态链接库文件.
将目录src下的lauxlib.h、lua.h、luaconf.h、lualib.h四个头文件以及刚刚生成的lib和dll文件取出待用.
把刚才的六个文件放置到我们的VC++工程文件夹下,在我们的C++代码中包含头文件以及链接库文件:
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "luaconf.h"
}
#pragma comment(lib,"lua.lib")
接下来就能在C++中使用我们的Lua语言.
方法二:
我们自己生成Lua的静态链接库.
1.创建一个VC10的win32控制台应用程序项目,项目名为lua,下一步选择静态库,不预编译头,将下载解压得到的目录src下的所有文件(除了Makefile)都加入工程中,然后编译得到一个lua.lib库文件,取出待用。
2.将目录src下的lauxlib.h、lua.h、luaconf.h、lualib.h四个头文件取出待用。
3.建立文件夹 lualib_include,在lualib_include中再创建文件夹lib和include,将刚才编译的liblua.lib文件添加到lib下,将刚才取出的几个头文件加入到include下。
4.在lualib_include文件夹外面创建一个luainc.h文件,在里面写入代码:
#pragma once
extern "C" {
#include"lualib_include/include/lua.h"
#include"lualib_include/include/lauxlib.h"
#include"lualib_include/include/lualib.h"
#include"lualib_include/include/luaconf.h"
}
#pragmacomment(lib,"lualib_include/lib/lua.lib")
这样一来以后要用LUA的时候只需要将lualib_include文件夹与luainc.h文件复制到工程文件夹下,然后在需要用到的地方#include"luainc.h"即可。
这两种方式的区别:
方式一生成的是动态链接库,我们的C++程序生成比较小,但要带上Lua51.dll文件
方式二生成的是静态链接库,我们的C++程序生成比较大,但不用带上Lua51.dll文件
在MFC中开始使用我们的Lua
我们要使用Lua, 在完成以上的环境搭建工作后, 还要在C++源代码中,还要做如下准备工作.
1. 首先我们要创建一个全局的Lua解释器指针lua_State*L = NULL;
2. 在窗口初始化函数中初始化这个指针L = luaL_newstate(); 并且装载我们Lua基本库luaL_openlibs(L);以方便C++调用Lua的函数,如print
注意,在我们不需要的时候,要将Lua解释器指针关闭掉: lua_close(L);
在程序中调用脚本的函数(扩充应用程序)?配置语言
假设在脚本中定义了一个函数:
function main(number)
number = number+ 1
return number
end
在我的C++代码中,我希望在某个时刻调用这个函数取得它的返回值,例如取角色血.
提供两种方式可以加载一个Lua脚本:
luaL_dofile
luaL_dostring |
首先,让我来简单的解释一下Lua解释器的工作机制,Lua解释器自身维护一个运行时栈,通过这个运行时栈,Lua解释器向主机程序传递参数,所以我们可以这样来得到一个脚本变量的值:
lua_pushstring(L, "var"); //将变量的名字放入栈
lua_gettatbl(L, LUA_GLOBALSINDEX);//变量的值现在栈顶
假设你在脚本中有一个变量var = 100
你可以这样来得到这个变量值:
int var = lua_tonumber(L, -1);
怎么样,是不是很简单?
Lua定义了一个宏让你简单的取得一个变量的值:
lua_getglobal(L,name)
我们可以这样来取得一个变量的值:
lua_getglobal(L, "var"); //将变量的名字放入栈,并将变量的值放到栈顶
int var = lua_tonumber(L, -1); |
在Lua中,函数等同于变量,所以我可以这样来取得这个函数:
lua_getglobal(L, "main");//将函数的名字放入栈,并将函数体放到栈顶
现在,我们可以调用这个函数,并传递给它正确的参数:
lua_pushnumber(L, 100); //将参数压栈
lua_pcall(L, 1, 1, 0); //调用函数,有一个参数,一个返回值
//返回值现在栈顶
int result = lua_tonumber(L, -1);
result 就是函数的返回值
脚本调用程序(Lua调用C)
Lua本身定位在一种轻量级的,灵活的,可扩充的脚本语言,这意味着你可以自由的扩充Lua,为你自己的游戏量身定做一个脚本语言。
你可以在主机程序中向脚本提供你自定的api,供脚本调用。
首先,我们定义一个函数
int foo(lua_State *L)
{
//首先取出脚本执行这个函数时压入栈的参数
//假设这个函数提供一个参数,有两个返回值
//get the first parameter
const char *par = lua_tostring(L, -1); //获取参数
printf("%s\n", par);
//push the first result
lua_pushnumber(L, 100);
//push the second result
lua_pushnumber(L, 200);
//return 2 result
return 2; //返回两个值
}
我们可以在脚本中这样调用这个函数
r1, r2 = foo("hello") //取得返回值
print(r1..r2)
完整的测试代码如下:
int main(int argc, char *argv[])
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
lua_register(L, "FOO", foo);
const char *buf = "r1, r2 = FOO ("hello")print(r1..r2)";
lua_dostring(L, buf);
lua_close(L);
return 0;
}
程序输出:
hello
100200 |
|