lua的C接口
来源:互联网 发布:iphone8值得买吗 知乎 编辑:程序博客网 时间:2024/05/16 07:18
用lua快一年了,因为引擎部分比较少改动,所以一直没用过它的C接口,都是在写脚本。年前看书时写了一个小的demo做学习用,好像当时遇到些困难,但是没有记录下来,几乎都忘了。这里贴点源码出来做备忘吧:)lua的语法还是比较简单,其官网(www.lua.org)上有电子文档(www.lua.org/pil/),看一看就会了。不过学会一门语言的语法跟用好一门语言还是两回事,好在它的源码也不多,多看看源码理解就深了。
首先说我比较讨厌lua的几个地方:
1、把数组和table混在一起,数组可以很方便取得size,而table就只能自己遍历去数。
2、没有continue,经常出现循环里面嵌套N层if。
3、最最无聊的就是变量默认是global的,要显示声明local才是本地变量。
大概就这几个公认的问题了,下面贴代码:)
程序实现了一个lua解释器,其实就是读入lua语句然后解释执行,用了readline是为了输入方便。另外启动的时候load了一个叫init.lua的脚本文件,提供了几个api供脚本使用,全部代码如下:(csdn怎么不提供附件功能呢)
main.hpp
#include <unistd.h>
#include <sys/param.h>
#include <errno.h>
#include <stdlib.h>
#include <iostream>
#include <readline/readline.h>
#include <readline/history.h>
#include <lua.hpp>
extern lua_State *L;
bool exelua(const char*);
bool init_script();
int lua_getcwd(lua_State*);
int lua_dir(lua_State*);
void register_api(lua_State*);
void create_table(lua_State*);
#include <sys/param.h>
#include <errno.h>
#include <stdlib.h>
#include <iostream>
#include <readline/readline.h>
#include <readline/history.h>
#include <lua.hpp>
extern lua_State *L;
bool exelua(const char*);
bool init_script();
int lua_getcwd(lua_State*);
int lua_dir(lua_State*);
void register_api(lua_State*);
void create_table(lua_State*);
main.cpp
#include "main.hpp"
lua_State *L;
int main(int argc, char** argv)
...{
L = luaL_newstate();//创建一个lua运行环境,可以传入一个内存管理参数
luaL_openlibs(L);//打开常用lib
if ( ! init_script() )//load脚本
return -1;
register_api(L);//注册api
create_table(L);//创建一个table
char* input = NULL;
while(1)
...{
input = readline(">>");//提示输入
if (input)
...{
if ( *input )
...{
if( exelua(input) )//执行输入的语句
add_history(input);//增加到历史命令
}
free(input);
input = NULL;
}
else
...{
break;
}
}
lua_close(L);
return 0;
}
bool exelua(const char* line)
...{
int error = luaL_loadbuffer(L, line, strlen(line), "line") || lua_pcall(L, 0, 0, 0);//load并执行
if ( error )
...{
std::cerr << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
return false;
}
return true;
}
bool init_script()
...{
if ( luaL_dofile(L, "init.lua") != 0 )
...{
std::cerr << "load init.lua failed ";
return false;
}
lua_pushnumber(L, 1);//传入参数
lua_getglobal(L, "__init__");//获取脚本中__init__变量
if ( lua_isfunction(L, -1) )//判断__init__是否一个函数
...{
if ( lua_pcall(L, 0, 1, NULL) != 0 )//调用__init__
...{
std::cerr << "call __init__ error ";
return false;
}
int ret = lua_tonumber(L, -1) || lua_toboolean(L, -1);//取得__init__的返回值
lua_pop(L, 1);
if ( !ret )
...{
std::cerr << "__init__ failed ";
return false;
}
}
return true;
}
lua_State *L;
int main(int argc, char** argv)
...{
L = luaL_newstate();//创建一个lua运行环境,可以传入一个内存管理参数
luaL_openlibs(L);//打开常用lib
if ( ! init_script() )//load脚本
return -1;
register_api(L);//注册api
create_table(L);//创建一个table
char* input = NULL;
while(1)
...{
input = readline(">>");//提示输入
if (input)
...{
if ( *input )
...{
if( exelua(input) )//执行输入的语句
add_history(input);//增加到历史命令
}
free(input);
input = NULL;
}
else
...{
break;
}
}
lua_close(L);
return 0;
}
bool exelua(const char* line)
...{
int error = luaL_loadbuffer(L, line, strlen(line), "line") || lua_pcall(L, 0, 0, 0);//load并执行
if ( error )
...{
std::cerr << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
return false;
}
return true;
}
bool init_script()
...{
if ( luaL_dofile(L, "init.lua") != 0 )
...{
std::cerr << "load init.lua failed ";
return false;
}
lua_pushnumber(L, 1);//传入参数
lua_getglobal(L, "__init__");//获取脚本中__init__变量
if ( lua_isfunction(L, -1) )//判断__init__是否一个函数
...{
if ( lua_pcall(L, 0, 1, NULL) != 0 )//调用__init__
...{
std::cerr << "call __init__ error ";
return false;
}
int ret = lua_tonumber(L, -1) || lua_toboolean(L, -1);//取得__init__的返回值
lua_pop(L, 1);
if ( !ret )
...{
std::cerr << "__init__ failed ";
return false;
}
}
return true;
}
api.cpp
#include <dirent.h>
#include "main.hpp"
int lua_getcwd(lua_State* L)//获取当前工作目录
...{
char path[MAXPATHLEN];
bzero(path, MAXPATHLEN);
if (lua_gettop(L) != 0 ) //不需要参数
...{
luaL_argerror(L, 0, "no arg expected");
return 0;
}
if ( !getcwd(path, MAXPATHLEN) )
...{
luaL_error(L, "getcwd error %d, %s", errno, strerror(errno));
return 0;
}
lua_pushlstring(L, path, strlen(path));//将返回值压栈
return 1;//返回返回值个数
}
int lua_dir(lua_State* L)//取得目录下元素
...{
const char* path = luaL_checkstring(L, 1);
DIR* dir = opendir(path);
if ( !dir )
...{
lua_pushnil(L);
lua_pushstring(L, strerror(errno));
return 2;
}
int i = 1;
struct dirent *ent;
lua_newtable(L);//把所有元素放到一个table中,以数组返回
while( ent = readdir(dir) )
...{
lua_pushnumber(L, i++);
lua_pushstring(L, ent->d_name);
lua_settable(L, -3);
}
closedir(dir);
return 1;
}
void register_api(lua_State* L)//注册api
...{
lua_register(L, "getcwd", lua_getcwd);//脚本中可以使用getcwd调用lua_getcwd
lua_register(L, "dir", lua_dir);
const luaL_Reg mylib[] =
...{
...{"getcwd", lua_getcwd},
...{"dir", lua_dir},
...{NULL, NULL},
};
luaL_register(L, "tlib", mylib);//注册一个名为tlib的模块,tlib.getcwd()
}
void create_table(lua_State* L)//创建一个table
...{
lua_newtable(L);
lua_pushnumber(L, 123);
lua_setfield(L, -2, "id");
lua_pushcfunction(L, lua_getcwd);
lua_setfield(L, -2, "fun");
lua_setglobal(L, "tb");
}
#include "main.hpp"
int lua_getcwd(lua_State* L)//获取当前工作目录
...{
char path[MAXPATHLEN];
bzero(path, MAXPATHLEN);
if (lua_gettop(L) != 0 ) //不需要参数
...{
luaL_argerror(L, 0, "no arg expected");
return 0;
}
if ( !getcwd(path, MAXPATHLEN) )
...{
luaL_error(L, "getcwd error %d, %s", errno, strerror(errno));
return 0;
}
lua_pushlstring(L, path, strlen(path));//将返回值压栈
return 1;//返回返回值个数
}
int lua_dir(lua_State* L)//取得目录下元素
...{
const char* path = luaL_checkstring(L, 1);
DIR* dir = opendir(path);
if ( !dir )
...{
lua_pushnil(L);
lua_pushstring(L, strerror(errno));
return 2;
}
int i = 1;
struct dirent *ent;
lua_newtable(L);//把所有元素放到一个table中,以数组返回
while( ent = readdir(dir) )
...{
lua_pushnumber(L, i++);
lua_pushstring(L, ent->d_name);
lua_settable(L, -3);
}
closedir(dir);
return 1;
}
void register_api(lua_State* L)//注册api
...{
lua_register(L, "getcwd", lua_getcwd);//脚本中可以使用getcwd调用lua_getcwd
lua_register(L, "dir", lua_dir);
const luaL_Reg mylib[] =
...{
...{"getcwd", lua_getcwd},
...{"dir", lua_dir},
...{NULL, NULL},
};
luaL_register(L, "tlib", mylib);//注册一个名为tlib的模块,tlib.getcwd()
}
void create_table(lua_State* L)//创建一个table
...{
lua_newtable(L);
lua_pushnumber(L, 123);
lua_setfield(L, -2, "id");
lua_pushcfunction(L, lua_getcwd);
lua_setfield(L, -2, "fun");
lua_setglobal(L, "tb");
}
init.lua
function __init__()
print("__init__ ok")
return 1;
end
print("__init__ ok")
return 1;
end
CPPFLAGS=-Wall -g -O0 -I /usr/local/include/lua51/
LIB=-L/usr/local/lib/lua51/ -llua -lreadline
CC=g++
SRC=main.cpp api.cpp
OBJ=${SRC:%.cpp=%.o}
all: depend main
depend:
@$(CC) -MM $(SRC) > .depend
-include .depend
main: $(OBJ)
$(CC) $(OBJ) $(CPPFLAGS) $(LIB) -o $@
clean:
-rm -rf *.o main .depend
LIB=-L/usr/local/lib/lua51/ -llua -lreadline
CC=g++
SRC=main.cpp api.cpp
OBJ=${SRC:%.cpp=%.o}
all: depend main
depend:
@$(CC) -MM $(SRC) > .depend
-include .depend
main: $(OBJ)
$(CC) $(OBJ) $(CPPFLAGS) $(LIB) -o $@
clean:
-rm -rf *.o main .depend
以上代码在freebsd 6.2 gcc 3.4.6 lua 5.1.2下编译通过。
- lua的C接口
- Lua 的C接口-解释器源码
- LUA C API接口
- lua的posix接口
- c接口导出到lua中使用
- cocos2d-x Lua 自定义类的Lua接口生成
- 使用luabind绑定box2d的lua接口
- [openwrt] uci 的shell和lua接口
- COCOS2D 之 lua 接口的使用
- lua -->c c-->lua
- c/c++混编,导出接口给lua调用
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- lua和c的交互
- C遍历lua的table
- lua的c api 总结
- 学习笔记
- 中小散户牛市亏钱六大原因
- 2万4单词库SQL2005备份+真人发声MP3库,提供下载
- ASP.NET FCKeditor 文本编辑器的使用
- Dev-C++开发的电脑三维动画
- lua的C接口
- 2008-3-10大盘分析
- ASCII 码
- 微软的面试题及答案-超变态但是很经典
- Struts应用之ActionForm
- 闰月的最后一天是非法日期吗?
- 使用内存硬盘--加速系统2
- 马云和史玉柱到底谁说了谎?
- at88sc programer/reader - 深圳密加技术 AT88SC(AT88SCXXXX)开发套件(兼读写编程器)