声明: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添加静态库项目(静态库项目的生成方法见此链接)

5.使用lua

lauxlib.h,lua.h,luaconf.h,lualib.h这几个头文件。

关于lua的使用,我直接用代码说明吧。

以下代码演示了lua的栈操作 ,执行内存脚本,加载脚本中定义的变量,执行脚本中定义的无参函数,执行脚本中定义的有参函数,脚本中调用C++函数等操作。

1. // lua_test.cpp : 定义控制台应用程序的入口点。  
2. //  
3.   
4. #include "stdafx.h"  
5.   
6. #include <iostream>    
7. #include <string>    
8.   
9. extern "C"  
10. {  
11. #include "lua.h"  
12. #include "lualib.h"  
13. #include "lauxlib.h"  
14. }  
15.   
16. using namespace std;   
17.   
18.   
19. int fcAdd(lua_State *lu)    
20. {    
21. int a = lua_tointeger(lu, 1);    
22. int b = lua_tointeger(lu, 2);    
23. //结果压栈    
24. return 1;           //返回1个结果    
25. }    
26.   
27.   
28. int _tmain(int argc, _TCHAR* argv[])  
29. {  
30.   
31. int nret = 0;    
32.   
33. /*创建Lua对象*/  
34.     lua_State* lu = luaL_newstate();  
35.     luaL_openlibs(lu);  
36.   
37.   
38. /*栈操作  */  
39. //压入一个int类型的数据,数值为1  
40.     lua_pushinteger(lu, 1);    
41. //压入一个int类型的数据,数值为3  
42.     lua_pushinteger(lu, 3);    
43. //获得栈中第一个元素(也就是刚刚放入的第一个元素“1”)  
44. int n = lua_tointeger(lu, 1);    
45. //获得栈中第二个元素  
46.     n = lua_tointeger(lu, 2);    
47. //获得栈中的元素总数(如果总数为0,表示空。前面放入两个,这里的值为2)  
48. int nStack = lua_gettop(lu);    
49. //剔除栈中元素(剔除两个,栈空)  
50.     lua_pop(lu, 2);    
51. //获得栈中元素总数  
52.     nStack = lua_gettop(lu);    
53.   
54. /*执行内存脚本*/  
55.   
56. //在lua脚本中,print函数是打印操作,print("Hello world")相当于打印一句Hello world。此时str相当于脚本中的打印操作  
57. "print (\"Hello world!\")";    
58. //把str加载到内存中,其中最后一个参数"name"是chunk名字,用于debug或者错误信息的标识  
59. "line");    
60. //调用函数。PS:lua_pcall的参数中n-nargs表示参数的个数,r-nresults表示...,errfunc表示  
61.     lua_pcall(lu, 0,0,0);    
62.     
63. /*加载脚本中定义的变量  */  
64. "../../luaScripts/test.lua");    
65. //压入aa名字(必须先压入需要取值的数据名,然后通过取值函数(例如tointeger) 从栈中取值)  
66. "aa");    
67. //压入bb名字  
68. "bb");    
69. //前面已经演示过传入正数索引调用tointeger,现在演示如果传入的参数为负数,则会从后开始取值  
70. int bb = lua_tointeger(lu, -1);    
71. int aa = lua_tointeger(lu, -2);    
72.         
73. /*执行脚本中定义的无参函数  */  
74. //压入hello函数名字,其实无论函数还是变量,都是通过压入名字然后去调用的。  
75. "hello");    
76. //参数nargs为0,表示调用的是无参的函数  
77.     nret = lua_pcall(lu, 0,0,0);    
78.         
79. /*执行脚本中定义的有参函数  */  
80. "fadd");    
81. //压入即将作为参数的对象  
82.     lua_pushnumber(lu, aa);    
83.     lua_pushnumber(lu, bb);    
84. //调用函数并获得返回结果(如果nret为0,表示调用成功,返回值会放入栈,通过取值即可获得。否则失败,失败时lua会产生失败信息放入栈,通过取值就可以获得错误信息)  
85.     nret = lua_pcall(lu, 2,1,0);    
86.     
87.   
88. "1 元素总数:" << lua_gettop(lu) << endl;  
89. if (nret != 0)    
90.     {    
91. //打印错误信息  
92. const char *pc = lua_tostring(lu, -1);    
93.         cout << pc;    
94.   
95. "2 元素总数:" << lua_gettop(lu) << endl;  
96.     }    
97. else    
98.     {    
99. //打印结果  
100.         nret = lua_tointeger(lu, -1);    
101. "调用脚本函数:" << endl;    
102. " + " << bb << " = " << nret << endl;    
103.   
104. "3 元素总数:" << lua_gettop(lu) << endl;  
105. //?  
106.         lua_pop(lu, 1);    
107. "4 元素总数:" << lua_gettop(lu) << endl;  
108.     }    
109.     
110. /*脚本中调用C++函数*/  
111. //压入c++函数  
112.     lua_pushcfunction(lu, fcAdd);    
113. //取出fcAdd函数使用  
114. "fcAdd");    
115. //压入脚本函数  
116. "fc");    
117. //压入参数  
118.     lua_pushnumber(lu, aa);    
119.     lua_pushnumber(lu, bb);    
120. //调用函数  
121.     nret = lua_pcall(lu, 2,1,0);    
122.     
123. if (nret != 0)    
124.     {    
125. const char *pc = lua_tostring(lu, -1);    
126.         cout << pc;    
127.     }    
128. else    
129.     {    
130.         nret = lua_tointeger(lu, -1);    
131. "调用C++函数:" << endl;    
132. " + " << bb << " = " << nret << endl;    
133.         lua_pop(lu, 1);    
134.     }    
135.         
136.     lua_close(lu);    
137. "pause");    
138. return 0;    
139. }


6.lua脚本的创建

lua脚本其实就是个文本文件,之后后缀名改为lua了,例如第五步的test.lua脚本,这里列出test.lua脚本的源码

1. aa=2;    
2. bb=3;    
3. function hello(a,b)    
4. "Hello in script!")    
5. end    
6. function fadd(a,b)    
7. return a+b    
8. end    
9. function fc(a,b)    
10. return fcAdd(a,b)    
11. end