lua与c交互都是用过lua_State*
类型的变量,并且是基于栈的。
文件: hello.c
#include <lua.h>
#include <lxlib.h>
#include <lualib.h>
/* 这里以lua5.1来示意 */
#define LUA_VERSION__ 51
/*
* 构造一个简单的函数
*/
static int hello(lua_State *L)
{
char const *str;
int age;
str = luaL_checkstring(L, 1); /* 传入的第一个参数是字符串(C风格的) */
age = luaL_checkint(L, 2); /* 传入的第二个参数是int型变量 */
char tmp[512];
snprintf(tmp, 512, "hello `%s`, your age is %d.", str, age);
lua_pushstring(L, tmp); /* 压入返回值 */
return 1; /* 只有一个返回值 */
}
/* lua中函数名和c中函数映射 */
static const struct luaL_Reg funs[] = {
{"say", hello},
{NULL, NULL},
};
/*
* lua中调用模块名为"hello"
*/
extern int luaopen_hello(lua_State *L)
{
/* 在lua5.1之后注册函数变化了,LUA_VERSION__是我自己定义的宏:) */
#if (LUA_VERSION__ > 51)
luaL_newlib(L, funs);
#else
/* lua5.1 根据luaL_newlib函数,我们可以明白这里的"hello"参数并没有多大用 */
luaL_register(L, "hello", funs);
#endif
return 1;
}
这里给出一个简单的使用方法。
$ # 由于是用c编写lua模块,所以并不需要链接lua的库,只需要其头文件,这里是lua5.1版本
$ gcc -o hello.so -shared -fPIC hello.c `pkg-config --cflags lua5.1`
local hello = require("hello")
print(hello.say("leetking", 21))
-- hello `leetking`, your age is 21.
只需要把打开函数修改为luaopen_module_submodule
,那么在lua中按照require("module.submodule")
来使用。
- 返回表
lua_newtable(L); /* index: -1 */
for (int i = 0; i <= nstr; ++i) {
lua_pushnumber(L, i); /* index: -2 */
lua_pushstring(L, strs[i]); /* index: -3 */
lua_settable(L, -3); /* 弹出i和strs[i]放到表里 */
}
/* 返回的结果形如{1: "str1", 2: "str2"} */
- 参数压入弹出函数
- lua_pushnil();
- lua_pushnumber();
- lua_pushstring();
- lua_pushlstring();
- lua_pushboolean();
- luaL_checkint();
- luaL_checklong();
- luaL_checkstring();
- luaL_checklstring();
lua5.1中不支持形如"\xff\xa0"
的十六进制字符串写法,但是是支持0xff
十六进制常量的。
@xueliu 感谢,确实是
lauxlib.h
这里作笔记时,笔误了