LUA的基础讲解

来源:互联网 发布:销售软件增值税税率 编辑:程序博客网 时间:2024/05/21 18:46

刚新学习了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 <stdio.h>

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 <stdio.h>

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 <stdio.h>

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)




原创粉丝点击