因为我接触C语言较多,现在跳过lua语法等基础知识,直接先用起来,后续再补充lua语法知识,本文通过C代码使用lua,环境为linux(ubuntu),其他环境也类似,举一反三。
(其实lua的语法和C也类似,当然也有一些是lua特有的特性)
一、lua代码下载和编译静态库
首先到lua官方网站下载代码,下载你所需要的版本即可。网址:www.lua.org。我下载的版本是5.1.5.
下载代码后,将源代码拷贝到ubuntu相应目录,并解压。
$ tar zxf lua-5.1.5.tar.gz
解压后,进入到目录进行编译。
$ cd lua-5.1.5/
执行make会报错,并提示你选择相应平台。选择平台后,再次make:
$ make linux
编译成功后,在src目录下有很多目标文件,其中就有liblua.a静态库。
如有编译报错,请对号入座:
1、链接静态库报错
连接器出现问题或被意外修改了,会报此错误
如:
/usr/bin/ld: line 1: syntax error near unexpected token `newline'
/usr/bin/ld: line 1: `!<arch>'
解决方案:
卸载再重新安装gnu二进制工具:
$ sudo apt-get autoremove binutils
$ sudo apt-get install binutils
看下gcc有没有安装,如果没有安装到的话,再安装一下gcc即可:
$ sudo apt-get install gcc
2、找不到头文件readline.h
因为lua依赖readline库
luaconf.h:275:31: fatal error: readline/readline.h: No such file or directory
解决方案:
安装readline:
$ sudo apt-get install libreadline-dev
如果还提示其他库找不到的话,继续安装即可。
二、编写测试代码
C代码如下:
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main(void)
{
char buff[256];
int error;
lua_State *L = lua_open();
//luaopen_base(L);
//luaopen_table(L);
//luaopen_io(L);
//luaopen_string(L);
//luaopen_math(L);
luaL_openlibs(L);
printf("lua open ok!\n");
while (fgets(buff, sizeof(buff), stdin) != NULL)
{
error = luaL_loadbuffer(L, buff, strlen(buff), "line") || lua_pcall(L, 0, 0, 0);
if(error)
{
fprintf(stderr, "%s", (char*)lua_tostring(L, -1));
lua_pop(L, 1);
}
}
lua_close(L);
return 0;
}
环境准备:
将之前编译的lua库拷贝到系统/usr/lib目录下,方便编译的时候连接;
将之前下载的lua代码的头文件拷贝到系统/usr/include目录下,这样方便编译;
编译报错和说明:
1、Error: “expected '(' before string constant”
报这个错是因为在C代码中加了extern "C" {,这个是在C++中使用的,在C环境中不需要。
2、找不到lua函数名
lua_test.c:(.text+0x1e): undefined reference to `luaL_newstate'
lua_test.c:(.text+0x2e): undefined reference to `luaopen_base'
lua_test.c:(.text+0x3a): undefined reference to `luaopen_table'
lua_test.c:(.text+0x46): undefined reference to `luaopen_io'
lua_test.c:(.text+0x52): undefined reference to `luaopen_string'
lua_test.c:(.text+0x5e): undefined reference to `luaopen_math'
lua_test.c:(.text+0xa5): undefined reference to `luaL_loadbuffer'
lua_test.c:(.text+0xcd): undefined reference to `lua_pcall'
lua_test.c:(.text+0x10b): undefined reference to `lua_tolstring'
lua_test.c:(.text+0x12b): undefined reference to `lua_settop'
lua_test.c:(.text+0x15c): undefined reference to `lua_close'
报这个错是因为没有连接lua库,就是之前我们编译好的库。
3、某些数学函数找不到定义
lua_test.c:21:36: warning: incompatible implicit declaration of built-in function‘strlen’[enabled by default]
/usr/lib/gcc/i686-linux-gnu/4.6/../../../../lib/liblua.a(lvm.o): In function `Arith':
lvm.c:(.text+0x468): undefined reference to `pow'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../../lib/liblua.a(lvm.o): In function `luaV_execute':
lvm.c:(.text+0x22ec): undefined reference to `pow'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../../lib/liblua.a(lmathlib.o): In function `math_tan':
lmathlib.c:(.text+0x16c): undefined reference to `tan'
/usr/lib/gcc/i686-linux-gnu/4.6/../../../../lib/liblua.a(lmathlib.o): In function `math_tanh':
... ...
报这个错是因为lua基础库中需要依赖数学库,因此在编译时需要链接数学库。注意链接库的顺序。
4、动态库加载报错
loadlib.c:(.text+0xa17): undefined reference to `dlsym'
loadlib.c:(.text+0xa74): undefined reference to `dlopen'
loadlib.c:(.text+0xa81): undefined reference to `dlerror'
loadlib.c:(.text+0xa99): undefined reference to `dlerror'
报这个错是因为lua中需要用到动态库,编译时需要连接动态库libdl.so,也是要注意连接顺序。
我使用的编译命令是:
$ gcc -g -o lua_test lua_test.c -llua -lm -ldl
三、运行
编译成功后如果能云新起来,则说明没问题,可以开启后面的编程和学习了。
这里运行时有一个报错:
PANIC: unprotected error in call to Lua API (no calling environment)
报这个错是因为版本差异,经过网上查找资料,lua 5.0之前的版本是逐个lua库open的。后面的版本都封装在一个函数中。Lua_Lopenlibs(L);见代码。
修改一下代码即可。
到这里C语言调用lua的使用方法和环境搭建就完成了,后续的学习和编程就是具体语法和使用。