- 论坛徽章:
- 0
|
一、前言
Lua是一种和C/C++结合非常紧密的脚本语言,效率极高。一般是对时间要求比较高的地方用C++写,而经常需要改动的地方用Lua写。
偶最近在学习Lua, 所以写出心得和大家共享. Lua是一种完全免费的脚本语言,它的官方网站在
http://www.lua.org
.在网站上可以下载到lua的源码, 没有可执行版本, 不过不用担心, 因为lua源码可以在任何一种C/C++的编译器上编译.
平台: PowerPC AMCC 440ep
交叉编译器: ppc_440ep-gcc
交叉编译环境:Debian/Ubuntu
二、下载 lua 源码包
这里可以下载到所有的版本
http://www.lua.org/ftp/
注:本文所用版本为 lua-5.0
三、使 lua-5.0 支持16进制数
由于我需要保存16进制数值,而只有lua-5.1 之后才支持16进制数,所以我们需要下载补丁。这个补丁也是我从网上搜的可以使lua-5.0版本支持table中用16进制数保存数值
![]()
文件:
lua-5.0-support_hex.tar.gz
大小:
185KB
下载:
下载
四、熟悉语法
网上可以很容易的搜到关于lua语法的文章,如果想了解更加详细的介绍可以下载
《Progamming in Lua》。
五、交叉编译移植lua
由于我得程序最终要在PowerPC上跑,所以需要交叉编译lua并移植到开发板上。其实用lua扩展自己的应用程序需要的只是lua的头文件和编译出来的静态库。
解压缩,并将补丁打入源码包:
tar zxvf lua-5.0.tar.gz
tar zxvf lua-5.0-support_hex.tar.gz
cp lua-5_0-hex_patch lua-5.0 ;将补丁拷贝到lua源码根目录下
patch -p1
修改配置文件设置交叉编译环境:
vi config
修改如下几行
CC= ppc_440ep-gcc ;交叉编译工具
STRIP= ppc_440ep-strip ;同上
INSTALL_ROOT= /home/work/lxg/usr/local ;安装路径(这个路径是我自己建立的)
交叉编译并安装到制定目录
make
make install
安装结束后会在/home/work/lxg/usr/local下生成四个文件夹:
bin lib include man
将 lib 和 include 下所有文件拷贝到交叉编译工具链的库和头文件的路径下(可以设置INSTALL_ROOT 然后 make install 直接安装 )
六、用lua扩展你的程序
在《Progamming in Lua》中第25章讲解了简单的扩展C程序的方法,所以我这里就不再说了,下面我只介绍下几个比较有用的扩展:
1、如何编译Lua扩展后的C程序?
2、Lua如何向Lua传递表格?
3、函数如何向Lua脚本中的函数传递表格?
4、C函数如何调用Lua脚本中的函数?
5、Lua脚本如何调用C语言中的函数?
1、如何编译Lua扩展后的C程序?
Lua扩展程序所用的API都是靠两个静态库实现的,因此编译的时候需要增加库链接的参数,另外还需要编译器的math库
首先程序中必须包含Lua的三个头文件
#include
#include
#include
其次,编译的时候需要链接库
$(CC) $(CFLAGS) -o $@ $
2、Lua如何向Lua传递表格?
问题概要:用lua写了个函数,返回的是一个表。需要在C里对返回的表里元素做二次处理。在C里我们可以通过lua_gettable()或者lua_rawget()来获取表里元素值,但使用这两个接口的前提是你得知道key,它才能给你value. 当然对于顺序下标倒无所谓,但恰巧这次我用到的是关联数组,下标是无规则字符串.这时候如何遍历出表里元素就是个问题.
lua_next()就成了比较合适的选择.下图对整个逻辑做了解释
file:///d://1.jpg
上图对简单的表遍历做了介绍, 但事实上的情况是我返回了一个二维表,如果你了解了lua_next()的处理过程,那下面的代码看起来就没什么问题了.
例如定义一个lua脚本 test.lua
table_1 = {0x00,0x11,0x22,0x33}
table_2 = {0x44,0x55,0x66,0x77}
下面的函数可以直接得到表中的16进制数
lua_State *L;
int main(void)
{
int t_idx;
//打开句柄
L= lua_open();
//加载各个库
luaopen_base(L);
luaopen_io(L);
luaopen_string(L);
luaopen_math(L);
//打开lua脚本
if(luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0,0))
printf("error!!!!!!!!!!!\r\n");
//将table_2的名字压入堆栈
lua_getglobal(L, "table_2");
if(!lua_istable(L, -1))
{
printf("is not a table \r\n");
return -1;
}
//将nil压栈
lua_pushnil(L);
//以nill作为索引取下一个值
while (lua_next(L, -2) != 0)
{
if(lua_isnumber(L,-1)) //判断元素类型,也可能是string
{
t_idx=lua_tonumber(L, -1);//获取元素的值
printf("0x%x \r\n",t_idx);
lua_remove(L,-1); //移除栈顶数
}
}
lua_remove(L,-1);//删除NIL
lua_close(L);
return 0;
}
上面的函数可以得到脚本中table_2中的每一个值,这样配合lua脚本可以轻松的定义和得到16进制数组。
3、函数如何向Lua脚本中的函数传递表格?
例如下面的test.lua脚本中定义了一个函数,该函数是从C程序中得到一个固定的参数n和多个参数。
注:"..."代表的多参数被默认保存在arg[]中,脚标从1开始。
command = {}
function checkSum(n,...)
arg[7]=math.mod((arg[2]+arg[3]+arg[4]+arg[5]+arg[6]),256)
for i=1,n+1 do
command=arg
end
return command
end
注:checkSum(n,...) 这样定义可以定义一个固定参数和多个参数
下面的函数就是将一个数组的成员个数和每个成员传递给lua的函数。
int checkSum(lua_State *L,int command_num,unsigned char *str)
{
int i;
lua_getglobal(L, "checkSum");
lua_pushnumber(L,command_num);
for(i=0;i
4、C函数如何调用Lua脚本中的函数?
见《 Progamming in Lua 》第25章第2节
5、Lua脚本如何调用C语言中的函数?
其实所有lua与C语言的数据交换都遵循堆栈FILO的规则,因此lua调用C语言中的函数在参数传递方面和上面讲到的方法相似。
例如lua中不支持位运算,我们可以在C中定义为lua所用的位运算函数。
int luaBitRshift(lua_State *L)
{
unsigned char data,num,result;
//lua调用的时候:luaBitRshift(arg1,arg2) arg1:数值 arg2:位移的位数
//得到的结果栈顶第一个数位arg2
if(!lua_isnumber(L, -1))
{
printf("luaBitRshift:[arg2] is not a number\n");
return -1;
}
num=((int)lua_tonumber(L, -1));
if(!lua_isnumber(L, -2))
{
printf("luaBitRshift:[arg1] is not a number\n");
return -1;
}
data=((int)lua_tonumber(L, -2));
result=data>>num;
lua_pushnumber(L, result);
return 1;
}
另外,还需为lua注册这个函数,让lua解释器知道这个函数。
lua_register(L, "luaBitRshift", luaBitRshift);
这样,在lua函数中就可以直接调用这个函数了。
command = {}
function checkSum(n,...)
local value = arg[1];
for i = 2, 7 do
value = luaBitXor(value,arg);
end;
arg[8] = math.mod(value, 256);
for i=1,n+1 do
command=arg
end
return command
end
更新中......
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/64853/showart_511247.html |
|