Lua与Luac的关系:
lua的编译方法:
lua源代码当中,提供了两个工具,lua.exe和luac.exe 他们的区别如下:
lua.exe,被称为解释器,也就是说,他可以启动一个控制台程序,然后直接输入lua的语法,进行解释执行,也可以直接运行lua为扩展名的脚本文件。
luac.exe,被称为编译器,他的目的是将符合lua语法的lua文件,编译为二进制文件。然后再lua.exe当中可以直接运行。编译器的目的来源于,lua脚本文件是明文的,另外在动态解释时,也会耗费更多时间。因此为了方便,可以直接使用使用luac.exe编译的二进制文件作为解释器的输入文件,起到保护密码和加速运行的目的。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
刚刚新学习了LUA的基础知识,特将基本的概念记录下来。
LUA的作用:LUA是一种非常轻量级的脚本语言,他的解释器只有200k左右,而且他是一种叫做嵌入式脚本语言,也就是说他是需要嵌入到宿主语言上运行的,而且可以跟宿主语言进行互通。这样提供了一种非常流行的开发模式,就是lua作为业务逻辑层,而c、c++等宿主语言则作为开发的底层API使用。此外,因为lua的灵活性,lua再某些场合,被开发出来,进行替代xml,或者ini等配置文件。
LUA的源代码下载路径:http://www.lua.org/ftp/ , 这里边包含了lua的各种版本。此外,LUA的开发使用的是存c语言的方式,因此他具有很好的跨平台特性,特可以运行在windows,linux,unix,mac,ios,android等等各种平台的系统。
lua的编译方法:
lua源代码当中,提供了两个工具,lua.exe和luac.exe 他们的区别如下:
lua.exe,被称为解释器,也就是说,他可以启动一个控制台程序,然后直接输入lua的语法,进行解释执行,也可以直接运行lua为扩展名的脚本文件。
luac.exe,被称为编译器,他的目的是将符合lua语法的lua文件,编译为二进制文件。然后再lua.exe当中可以直接运行。编译器的目的来源于,lua脚本文件是明文的,另外在动态解释时,也会耗费更多时间。因此为了方便,可以直接使用使用luac.exe编译的二进制文件作为解释器的输入文件,起到保护密码和加速运行的目的。
LUA的具体编译方法:
第1步:
从官方主页www.lua.org下载Lua源代码,最新版本为5.1.2。
解压之后找到“src”文件夹,这里面就是Lua了,不过还不能直接使用。
第2步:
使用任意ANSI C编译器,在这里使用VS2005编译LUA。具体步骤如下:
1、新建一个空的Console工程,在这里该工程名暂为“lua”
2、将src中的文件全部拷贝到该项目文件夹下
3、根据生成的文件来添加需要编译的文件
4、使用Release配置来进行编译
以下是各类生成文件的详细说明:
静态库文件lua.lib
1、添加除了“lua.c”与“luac.c”以外的全部文件到工程
2、更改[项目属性]->[配置属性]->[常规]->[项目类型]为“静态库文件(.lib)”
解释器lua.exe
1、添加除了“luac.c”以外的全部文件到工程
2、更改Release状态下[项目属性]->[配置属性]->[常规]->[项目类型]为“应用程序(.exe)”
编译器luac.exe
3.1、添加除了“lua.c”以外的全部文件到工程
3.2、更改Release状态下[项目属性]->[配置属性]->[常规]->[项目类型]为“应用程序(.exe)”
注意:该文件生成时的名字为lua.exe,因为该项目名称为“lua”。如果之前生成过解释器lua.exe,则应该将解释器移走之后再生成。
LUA与C、C++的互调方法
1 c程序中调用lua脚本: 直接调用法
- 编写lua脚本
- 编写C函数,然后使用lua提供的api函数直接调用lua脚本,完成lua的运行。
例一:
main.cpp
//————————————————–
#include
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
/* LUA接口声明*/
lua_State* L;
int main ( int argc, char *argv[] )
{
/* 初始化 Lua */
L = lua_open();
/*载入LUA库 */
lua_baselibopen(L);
/* 运行LUA脚本 */
lua_dofile(L, "test.lua");
/* 清除 Lua */
lua_close(L);
return 0;
}
脚本test.lua:
用记事本写入以下代码,改扩展名为lua即可
– simple test
print "Hello, World!"
2 c程序中调用lua脚本: 间接调用法,即C语言直接调用LUA当中的某个函数的方法。
- 编写lua文件,并编写符合lua语法的函数
- 编写c文件,并编写堆栈调用关系的c函数,这个c函数要求与lua提供的模板函数对应。
- 在c主函数当中,调用c编写的符合lua提供的模板函数的对应c函数。
- 上述过程是必须的。
首先用记事本写个Lua文件。
—-fun.lua——–
function add ( x, y )
return x + y
end
为了调用一个LUA函数,我们首先要把函数压栈。这个函数的结果由参数决定,所以,我们要调用函数将需要lua_call(),调用这个函数之后,返回的结果将在堆栈中存在。
整个步骤:
1.用lua_getglobal()把add函数放入堆栈
2.用lua_pushnumber()把第一个参数压入堆栈
3.用lua_pushnumber()把第二个参数压入堆栈
4.用lua_call()调用函数。
5,现在用lua_tonumber从堆栈头取出结果
6,最后用lua_pop从堆栈中移除结果值。
代码:luaadd.cpp
如果你喜欢用C代替C++,改名为luaadd.c,并且除去
extern "C"即可
#include
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
/* the Lua interpreter */
lua_State* L;
int luaadd ( int x, int y )
{
int sum;
/* the function name */
lua_getglobal(L, "add");
/* the first argument */
lua_pushnumber(L, x);
/* the second argument */
lua_pushnumber(L, y);
/* call the function with 2
arguments, return 1 result */
lua_call(L, 2, 1);
/* get the result */
sum = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
return sum;
}
int main ( int argc, char *argv[] )
{
int sum;
/* initialize Lua */
L = lua_open();
/* load Lua base libraries */
lua_baselibopen(L);
/* load the script */
lua_dofile(L, "add.lua");
/* call the add function */
sum = luaadd( 10, 15 );
/* print the result */
printf( "The sum is %d\n", sum );
/* cleanup Lua */
lua_close(L);
return 0;
}
3 lua中调用c函数
我们用C/C++创建一个函数并告诉Lua解释器,然后在Lua中调用这个函数并使用函数的返回值。
定义一个C/C++函数:
要想C/C++中的函数能被Lua调用,函数定义必须这样:
代码:typedef int (*lua_CFunction) (lua_State *L);
也 就是说,函数必须以Lua解释器作为参数,并且返回值为int类型。既然Lua解释器作为函数的参数,那么实际上函数可以从栈中取得任意多个参数。下面我 们将看到,返回的整数值代表入栈的值的数目。如果有一个C/C++函数,你想在Lua中调用他,很容易封装一下就可以满足上述要求。
下面的C++的average函数例子中,可以清楚地看到Lua中调用C/C++函数是如何实现的。
1. lua_gettop()返回栈顶的下标索引,由于Lua中栈的下标从1开始,这个返回值实际上也就是函数参数的个数。
2. For循环计算各个参数总和。
3. Average的参数是通过调用lua_pushnumber()入栈的。
4. 然后参数之和被入栈。
5. 最后,函数返回值为2,表明有两个返回值,并且已经入栈。
函数被定义之后,我们必须告诉Lua编译器他的存在,这在main()函数中,在Lua解释器被初始化,类库加载之后完成的。
将下面的代码保存为luaavg.cpp,如果你喜欢用C而不是C++,需要保存文件为luatest.c并且把extern去掉。
#include
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
/* the Lua interpreter */
lua_State* L;
static int average(lua_State *L)
{
/* get number of arguments */
int n = lua_gettop(L);
double sum = 0;
int i;
/* loop through each argument */
for (i = 1; i <= n; i++)
{
/* total the arguments */
sum += lua_tonumber(L, i);
}
/* push the average */
lua_pushnumber(L, sum / n);
/* push the sum */
lua_pushnumber(L, sum);
/* return the number of results */
return 2;
}
int main ( int argc, char *argv[] )
{
/* initialize Lua */
L = lua_open();
/* load Lua base libraries */
lua_baselibopen(L);
/* register our function */
lua_register(L, "average", average);
/* run the script */
lua_dofile(L, "avg.lua");
/* cleanup Lua */
lua_close(L);
return 0;
}
此时的lua脚本可以编写如下:
-------以下是Lua脚本--------
--test.lua
a=100
b=100
aver,sum = average(a,b)
--------------------------------------------------------
--------------------------------------------------------
--------------------------------------------------------------------------------------
转载地址:http://blog.csdn.net/dongdongdongjl/article/details/8629704