声明:lua是一个跨平台的脚本语言,在linux下也可以使用,但是我目前只使用过windows,这篇文章也是在windows下的编程。
1.lua的简介
百度百科的简介:
Lua 是一个小巧的脚本语言。是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。Lua 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。
2.下载lua
lua官网的下载页面:http://www.lua.org/download.html
3.lua包含的文件
下载后的lua是一个压缩包,解压后可以获得doc和src文件夹,还有makefile和readme文件。
doc文件夹下主要有lua的api文档
src文件夹包含lua的源码
(lua压缩包并不包含lib文件,lib文件直接通过vs去编译lua源代码就可以生成lib了,方法见第四步)
4.生成lua lib文件。
使用visual studio添加静态库项目(静态库项目的生成方法见此链接http://blog.csdn.net/xv_ly15/article/details/8548791)
5.使用lua
在生成lib文件的步骤中的链接能看到如何在项目中使用lib,lua的使用同样需要使用lib,除了添加lib,还需要添加lauxlib.h,lua.h,luaconf.h,lualib.h这几个头文件。
关于lua的使用,我直接用代码说明吧。
以下代码演示了lua的栈操作 ,执行内存脚本,加载脚本中定义的变量,执行脚本中定义的无参函数,执行脚本中定义的有参函数,脚本中调用C++函数等操作。
- // lua_test.cpp : 定义控制台应用程序的入口点。
- //
- #include "stdafx.h"
- #include <iostream>
- #include <string>
- extern "C"
- {
- #include "lua.h"
- #include "lualib.h"
- #include "lauxlib.h"
- }
- using namespace std;
- int fcAdd(lua_State *lu)
- {
- int a = lua_tointeger(lu, 1);
- int b = lua_tointeger(lu, 2);
- lua_pushnumber(lu, a+b); //结果压栈
- return 1; //返回1个结果
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- int nret = 0;
- /*创建Lua对象*/
- lua_State* lu = luaL_newstate();
- luaL_openlibs(lu);
- /*栈操作 */
- //压入一个int类型的数据,数值为1
- lua_pushinteger(lu, 1);
- //压入一个int类型的数据,数值为3
- lua_pushinteger(lu, 3);
- //获得栈中第一个元素(也就是刚刚放入的第一个元素“1”)
- int n = lua_tointeger(lu, 1);
- //获得栈中第二个元素
- n = lua_tointeger(lu, 2);
- //获得栈中的元素总数(如果总数为0,表示空。前面放入两个,这里的值为2)
- int nStack = lua_gettop(lu);
- //剔除栈中元素(剔除两个,栈空)
- lua_pop(lu, 2);
- //获得栈中元素总数
- nStack = lua_gettop(lu);
- /*执行内存脚本*/
- //在lua脚本中,print函数是打印操作,print("Hello world")相当于打印一句Hello world。此时str相当于脚本中的打印操作
- string str = "print (\"Hello world!\")";
- //把str加载到内存中,其中最后一个参数"name"是chunk名字,用于debug或者错误信息的标识
- luaL_loadbuffer(lu, str.c_str(), str.length(), "line");
- //调用函数。PS:lua_pcall的参数中n-nargs表示参数的个数,r-nresults表示...,errfunc表示
- lua_pcall(lu, 0,0,0);
- /*加载脚本中定义的变量 */
- nret = luaL_dofile(lu, "../../luaScripts/test.lua");
- //压入aa名字(必须先压入需要取值的数据名,然后通过取值函数(例如tointeger) 从栈中取值)
- lua_getglobal(lu, "aa");
- //压入bb名字
- lua_getglobal(lu, "bb");
- //前面已经演示过传入正数索引调用tointeger,现在演示如果传入的参数为负数,则会从后开始取值
- int bb = lua_tointeger(lu, -1);
- int aa = lua_tointeger(lu, -2);
- /*执行脚本中定义的无参函数 */
- //压入hello函数名字,其实无论函数还是变量,都是通过压入名字然后去调用的。
- lua_getglobal(lu, "hello");
- //参数nargs为0,表示调用的是无参的函数
- nret = lua_pcall(lu, 0,0,0);
- /*执行脚本中定义的有参函数 */
- lua_getglobal(lu, "fadd");
- //压入即将作为参数的对象
- lua_pushnumber(lu, aa);
- lua_pushnumber(lu, bb);
- //调用函数并获得返回结果(如果nret为0,表示调用成功,返回值会放入栈,通过取值即可获得。否则失败,失败时lua会产生失败信息放入栈,通过取值就可以获得错误信息)
- nret = lua_pcall(lu, 2,1,0);
- cout << "1 元素总数:" << lua_gettop(lu) << endl;
- if (nret != 0)
- {
- //打印错误信息
- const char *pc = lua_tostring(lu, -1);
- cout << pc;
- cout << "2 元素总数:" << lua_gettop(lu) << endl;
- }
- else
- {
- //打印结果
- nret = lua_tointeger(lu, -1);
- cout << "调用脚本函数:" << endl;
- cout << aa << " + " << bb << " = " << nret << endl;
- cout << "3 元素总数:" << lua_gettop(lu) << endl;
- //?
- lua_pop(lu, 1);
- cout << "4 元素总数:" << lua_gettop(lu) << endl;
- }
- /*脚本中调用C++函数*/
- //压入c++函数
- lua_pushcfunction(lu, fcAdd);
- //取出fcAdd函数使用
- lua_setglobal(lu, "fcAdd");
- //压入脚本函数
- lua_getglobal(lu, "fc");
- //压入参数
- lua_pushnumber(lu, aa);
- lua_pushnumber(lu, bb);
- //调用函数
- nret = lua_pcall(lu, 2,1,0);
- if (nret != 0)
- {
- const char *pc = lua_tostring(lu, -1);
- cout << pc;
- }
- else
- {
- nret = lua_tointeger(lu, -1);
- cout << "调用C++函数:" << endl;
- cout << aa << " + " << bb << " = " << nret << endl;
- lua_pop(lu, 1);
- }
- lua_close(lu);
- std::system("pause");
- return 0;
- }
(代码参考如下博客:http://blog.csdn.net/shellching/article/details/7202913,我只是做了更详细的说明和使用体验,部分言语可能不当,因为此时我还是个初学者。)
6.lua脚本的创建
lua脚本其实就是个文本文件,之后后缀名改为lua了,例如第五步的test.lua脚本,这里列出test.lua脚本的源码
- aa=2;
- bb=3;
- function hello(a,b)
- print ("Hello in script!")
- end
- function fadd(a,b)
- return a+b
- end
- function fc(a,b)
- return fcAdd(a,b)
- end