本文主要包含Redis源码学习-Lua脚本,redis源码-lua等服务器相关知识,网友希望可以进行参考
Redis源码学习-Lua脚本,redis源码-lua
Redis源码学习-Lua脚本
1.Sublime Text配置
我是在Win7下,用Sublime Text + Cygwin开发的,配置方法请参考《Sublime Text 3下C/C++开发环境搭建》。
要注意的是:在Cygwin中安装Lua解析器后,SublimeClang插件就能识别出可饮用的Lua头文件了,因为Build System中我们已经配置过"-I", "D:\\cygwin64\\usr\\include",而新安装的Lua头文件会添加到这里。但是,编译时却无法链接到头文件对应的动态链接库。此时,还需要添加一个链接选项lua5.1,修改后的完整Build System配置文件如下:
{
"path": "D:\\cygwin64\\bin",
"cmd": ["gcc", "-I", "D:\\cygwin64\\usr\\include", "${file}", "-o", "${file_path}/${file_base_name}", "-lm", "-llua5.1", "-Wall", "&", "start", "${file_path}/${file_base_name}.exe"],
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"working_dir": "${file_path}",
"selector": "source.c, source.c++",
"shell": true,
"variants":
[
{
"name": "Run::Cygwin",
"cmd": [ "start", "${file_path}/${file_base_name}.exe"]
}
]
}
2.Lua基础
2.1 执行脚本
首先创建一个最简单的helloworld脚本hello.lua:
print("helloworld!")
下面详细解释一下从C代码中如何执行Lua脚本文件。不管是如何执行,Lua脚本的执行过程都分为以下五步。以下面一段代码框架适用于后面所有示例程序:
- 初始化解释器:lua_open是一个宏定义,等同于luaL_newstate()。创建出的lua_state也暗示了,Lua解释器不使用C全局变量,而是将所有状态都保存到lua_state这个数据结构中。
- 加载类库:luaL_openLibs()加载常用类库,如core、table、string、math等等。
- 加载并编译代码/脚本文件:通常由luaL_loadfile()或luaL_loadbuffer()来完成,注意这只会将Lua代码编译好,并不会真正执行。下面例子中lua_dofile等同于luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0),两步合并为一步了。
- 执行代码/脚本文件:由lua_pcall()完成,会根据当前栈上的函数名、参数执行。当错误时处理方式与上一步加载雷同,都是打印异常日志,然后从栈上弹出错误处理器,最后直接返回或退出。
- 清理释放:lua_close()清理释放解释器占用的资源。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
void execute_from_script(char *filename);
int main(int argc, char const *argv[])
{
execute_from_script("hello.lua");
return 0;
}
/**
* Execute from Lua script.
* @param filename script file name
*/
void execute_from_script(char *filename)
{
/* Lua interpreter */
lua_State *lua = lua_open();
/* Open Lua standard lib: io, string... */
luaL_openlibs(lua);
/* Execute code in script */
if (luaL_dofile(lua, filename)) {
fprintf(stderr, "Error when executing script: %s, %s\n",
filename, lua_tostring(lua, -1));
/* Remove error handler */
lua_pop(lua, 1);
return;
}
/* Release all resource used */
lua_close(lua);
}
2.2 执行代码
为了简化后面的示例代码,对错误处理统一封装成bail()函数:
void bail(lua_State *lua, char *msg, char *arg)
{
fprintf(stderr, "%s %s: %s\n", msg, arg, lua_tostring(lua, -1));
exit(-1);
}
这一次我们不单独创建一个Lua脚本文件,而是将Lua代码嵌入到C代码中直接执行!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
void execute_from_code(char *code);
int main(int argc, char const *argv[])
{
execute_from_code("print(\"hello world!!!\")");
return 0;
}
/**
* Execute Lua command directly.
* @param code Lua command
*/
void execute_from_code(char *code)
{
lua_State *lua = lua_open();
luaL_openlibs(lua);
// Load & compile command and execute immediately
if (luaL_loadbuffer(lua, code, strlen(code), "line")
|| lua_pcall(lua, 0, 0, 0))
bail(lua, "Error when executing code", code);
lua_close(lua);

