Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1347437
  • 博文数量: 118
  • 博客积分: 3888
  • 博客等级: 中校
  • 技术积分: 2940
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-10 18:15
个人简介

一看二做三总结

文章分类

全部博文(118)

分类: LINUX

2015-03-17 15:17:48


参考文档:
Lua 5.0 Reference manual
http://www.cnblogs.com/pied/archive/2012/10/26/2741601.html

根据Lua的官方文档,Lua的目标是作为通用语言的扩展。它是一种强大的、轻量级的,可嵌入的脚本语言。
其优点如下:
1. 可嵌入其他语言(一般是C/C++吧),对于想要使用Lua的程序,只需要在编译时加入libluax.x.so库。这个库就包含了一个完整的lua解释器。而lua脚本中也可以方便的调用宿主语言实现的各种函数。
2. 轻量级。只需要包含一个库文件,确实够轻量级的。
3. 强大。相对与通用语言,Lua确实强大很多,虽然Lua是个轻量级的脚本语言,但仍然具有脚本语言所天生具有的易理解性与强大的文本处理能力。
4. 不需编译。与一般脚本语言一样,Lua是解释性语言,因此可以快速的修改而不需编译。非常适用于经常需要变动的流程。

下面就来体验下Lua的方便与快捷,先从“Hello world”开始:

****** 测试环境为Ubuntu 14.04 ******

1. 首先准备一个lua脚本:
hello.lua:

点击(此处)折叠或打开

  1. /* hello.lua */
  2. print("Hello world")

2. 准备一个C程序:
test_lua.c:

点击(此处)折叠或打开

  1. /* test_lua.c */
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. /* headers for lua */
  5. #include <lua.h>
  6. #include <lauxlib.h>
  7.  
  8. int main(int argc, const char *argv[])
  9. {
  10. lua_State *L = luaL_newstate(); /* Create new lua state variable */
  11.  
  12. /* Load Lua libraries, otherwise, the lua function in *.lua will be nil */
  13. luaL_openlibs(L);
  14.  
  15. if(luaL_loadfile(L,"hello.lua")) { /* load the lua script file */
  16. printf("luaL_loadfile error: %s\n", lua_tostring(L,-1));
  17. exit(1);
  18. }
  19.  
  20. if(lua_pcall(L,0,0,0)) { /* Run the loaded lua file */
  21. printf("lua_pcall error: %s\n", lua_tostring(L,-1));
  22. exit(2);
  23. }
  24.  
  25. lua_close(L); /* Close the lua state variable */
  26.  
  27. exit(0);
  28. }
C语言调用Lua时,每一个Lua脚本文件用一个lua_State结构体(例子中为L)表示,该结构体通过luaL_newstate()创建,并通过lua_close()释放。
luaL_openlibs()用于为lua_State结构体绑定库函数,如果不调用这个函数,照样可以执行Lua脚本,但无法调用任何Lua的库函数。
luaL_Loadfile()用于载入用户自己编写的Lua脚本。载入后就可以进行调用了。这个函数相当于对Lua脚本进行编译与链接。此时该脚本还没有被执行,因此如果此时去获取脚本中的全局变量,则变量为空。
lua_pcall()用于执行脚本,第一个参数L就是lua_State结构体,第二个参数是Lua脚本中的函数名,如果为空,则会从头执行整个脚本。第二个参数为入参个数,第三个参数为出参个数。入参与出参通过堆栈的方式传递,本例中没有用到,因此个数都是0。
lua_tostring()用于以字符串形式打印栈中信息。如果脚本编译错误,则luaL_loadfile返回非0;如果脚本执行出现错误,则lua_pcall()回非0。这两种情况下,错误信息都会被存入栈首,使用lua_tostring(L, -1)则可以打印出错误信息。

3. 编译test_lua.c:
gcc ./test_lua.c -llua5.2 -I/usr/include/lua5.2 
(如发生错误,请参考最后的QA)

4. 执行a.out
./a.out
Hello world

5. 现在可以试试嵌入式脚本的好处了,修改hello.lua如下:
hello.lua:

点击(此处)折叠或打开

  1. /* hello.lua */
  2. print("Hello world")
  3. print("see you")
  4. print("Bye")
不需要再重新编译,直接执行a.out
./a.out
Hello world
See you
Bye

6. 总结
通过上面的例子,可以看到Lua与C语言可以实现无缝连接,确实是对C语言的扩展!!
而且Lua可以实现与C语言函数级的互相调用,那么是不是可以认为C+lua是一种新的语言呢?

QA:

Q: 编译时显示 “fatal error: lua.h: No such file or directory”

A: 调用“locate lua.h", 选择“/usr/include”下的lua.h。把头文件路径假jia入编译参数。
如我机器上的路径为:
/usr/include/lua5.2/lua.h
/usr/include/lua5.2/lua.hpp
所以编译命令为 gcc ./test_lua.c -llua5.2 -I/usr/include/lua5.2

Q: 执行“locate lua.h”时找不到lua.h

A: Ubuntu上需要单独安装dev库,执行下面的命令
sudo apt-get install liblua5.x-dev
sudo updatedab
(x的值根据lua的版本号定:“lua -v”)

Q: 编译时显示如下信息:
test_lua.c:(.text+0x10): undefined reference to `luaL_newstate'
test_lua.c:(.text+0x25): undefined reference to `luaL_openlibs'
test_lua.c:(.text+0x3b): undefined reference to `luaL_loadfilex'
test_lua.c:(.text+0x55): undefined reference to `lua_tolstring'
test_lua.c:(.text+0x98): undefined reference to `lua_pcallk'
test_lua.c:(.text+0xb2): undefined reference to `lua_tolstring'
test_lua.c:(.text+0xda): undefined reference to `lua_close'

A: 这是因为没有找到lua的库,执行“locate liblua”
一般lua的库在“/usr/lib”下,如我执行时显示如下:
/usr/lib/x86_64-linux-gnu/liblua5.2.a
/usr/lib/x86_64-linux-gnu/liblua5.2.so
因此编译命令修改为:gcc ./test_lua.c -llua5.2 -I/usr/include/lua5.2

阅读(3066) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~