您的位置:首页 > 编程语言 > Lua

skynet lua服务常用API

2017-09-13 12:02 796 查看


4.4 – C闭包

当 C 函数被创建出来, 我们有可能会把一些值关联在一起, 也就是创建一个 C 闭包 (参见
lua_pushcclosure
);
这些被关联起来的值被叫做 上值 , 它们可以在函数被调用的时候访问的到。

无论何时去调用 C 函数, 函数的上值都可以用伪索引定位。 我们可以用
lua_upvalueindex
这个宏来生成这些伪索引。
第一个关联到函数的值放在
lua_upvalueindex(1)
位置处,依此类推。 使用
lua_upvalueindex(n)
时,
若 n 大于当前函数的总上值个数 (但不可以大于 256)会产生一个可接受的但无效的索引。
int lua_upvalueindex (int i);


返回当前运行的函数(参见 §4.4)的第
i
个上值的伪索引。
void *lua_touserdata (lua_State *L, int index);


如果给定索引处的值是一个完全用户数据, 函数返回其内存块的地址。 如果值是一个轻量用户数据, 那么就返回它表示的指针。 否则,返回
NULL


struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));

// 完成服务的实例化,执行服务lua代码

static int
_init(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz) {

lua_State *L = l->L;

l->ctx = ctx;

lua_gc(L, LUA_GCSTOP, 0);

lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */

lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");

luaL_openlibs(L);

lua_pushlightuserdata(L, ctx);

lua_setfield(L, LUA_REGISTRYINDEX, "skynet_context");

void luaL_checktype (lua_State *L, int arg, int t);


检查函数的第
arg
个参数的类型是否是
t
。 参见
lua_type
查阅类型
t
的编码。

int lua_toboolean (lua_State *L, int index);


把给定索引处的 Lua 值转换为一个 C 中的布尔量( 0 或是 1 )。 和 Lua 中做的所有测试一样,
lua_toboolean
会把任何不同于 falsenil 的值当作真返回;
否则就返回假。 (如果你想只接收真正的 boolean 值, 就需要使用
lua_isboolean
来测试值的类型。)
void lua_settop (lua_State *L, int index);


参数允许传入任何索引以及 0 。 它将把堆栈的栈顶设为这个索引。 如果新的栈顶比原来的大, 超出部分的新元素将被填为 nil 。 如果
index
为 0 , 把栈上所有元素移除。

void lua_pushcfunction (lua_State *L, lua_CFunction f);


将一个 C 函数压栈。 这个函数接收一个 C 函数指针, 并将一个类型为
function
的 Lua 值压栈。 当这个栈顶的值被调用时,将触发对应的 C 函数。

注册到 Lua 中的任何函数都必须遵循正确的协议来接收参数和返回值 (参见
lua_CFunction
)。

lua_pushcfunction
是作为一个宏定义出现的:
#define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)


void lua_rawsetp (lua_State *L, int index, const void *p);


等价于
t[k] = v
, 这里的
t
是指给定索引处的表,
k
是指针
p
对应的轻量用户数据。
v
是栈顶的值。

这个函数会将值弹出栈。 赋值是直接的;即不会触发元方法。

static int
_callback(lua_State *L) {

struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));

int forward = lua_toboolean(L, 2);

luaL_checktype(L,1,LUA_TFUNCTION); // 取到上述c.callback(F)的F

lua_settop(L,1);

lua_rawsetp(L, LUA_REGISTRYINDEX, _cb); // 记录lua函数F到_cb这个索引位置
_cb:static int _cb(...)

userdata 类型允许将 C 中的数据保存在 Lua 变量中。 用户数据类型的值是一个内存块, 有两种用户数据:
完全用户数据 ,指一块由 Lua 管理的内存对应的对象; 轻量用户数据 ,则指一个简单的 C 指针。 用户数据在 Lua 中除了赋值与相等性判断之外没有其他预定义的操作。 通过使用 元表 ,程序员可以给完全用户数据定义一系列的操作 (参见 §2.4)。 你只能通过 C API 而无法在 Lua 代码中创建或者修改用户数据的值, 这保证了数据仅被宿主程序所控制。

int lua_rawgeti (lua_State *L, int index, lua_Integer n);


t
的值压栈, 这里的
t
是指给定索引处的表。 这是一次直接访问;就是说,它不会触发元方法。

返回入栈值的类型。

lua_State *lua_tothread (lua_State *L, int index);


把给定索引处的值转换为一个 Lua 线程 (表示为
lua_State*
)。 这个值必须是一个线程; 否则函数返回
NULL


int lua_rawgetp (lua_State *L, int index, const void *p);


t[k]
的值压栈, 这里的
t
是指给定索引处的表,
k
是指针
p
对应的轻量用户数据。
这是一次直接访问;就是说,它不会触发元方法。

返回入栈值的类型。
LUA_RIDX_MAINTHREAD: 注册表中这个索引下是状态机的主线程。 (主线程和状态机同时被创建出来。)

LUA_RIDX_GLOBALS: 注册表的这个索引下是全局环境。

int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);


以保护模式调用一个函数。

nargs
nresults
的含义与
lua_call
中的相同。
如果在调用过程中没有发生错误,
lua_pcall
的行为和
lua_call
完全一致。
但是,如果有错误发生的话,
lua_pcall
会捕获它,
然后把唯一的值(错误消息)压栈,然后返回错误码。 同
lua_call
一样,
lua_pcall
总是把函数本身和它的参数从栈上移除。

如果
msgh
是 0 , 返回在栈顶的错误消息就和原始错误消息完全一致。 否则,
msgh
就被当成是 错误处理函数 在栈上的索引位置。
(在当前的实现里,这个索引不能是伪索引。) 在发生运行时错误时, 这个函数会被调用而参数就是错误消息。 错误处理函数的返回值将被
lua_pcall
作为错误消息返回在堆栈上。

典型的用法中,错误处理函数被用来给错误消息加上更多的调试信息, 比如栈跟踪信息。 这些信息在
lua_pcall
返回后,
由于栈已经展开,所以收集不到了。

lua_pcall
函数会返回下列常数
(定义在
lua.h
内)中的一个:

LUA_OK (0): 成功。

LUA_ERRRUN: 运行时错误。

LUA_ERRMEM: 内存分配错误。对于这种错,Lua 不会调用错误处理函数。

LUA_ERRERR: 在运行错误处理函数时发生的错误。

LUA_ERRGCMM: 在运行 __gc 元方法时发生的错误。 (这个错误和被调用的函数无关。)

---------------------------

dispatch(type, func) 为 type 类型的消息设定一个处理函数。

dispatch_message(typeid, msg, sz, session, source) 默认的消息处理过程,由 C 层传递给它消息的五元组:消息类型 id 、指针、长度、session 号、消息源地址。

ret(msg, sz) 将打包好的消息回应给当前任务的请求源头。
retpack(...) 将消息用 pack 打包,并调用 ret 回应。
response([packfunc]) 生成一个回应函数,用于在将来回应当前任务。当消息不使用默认的 lua 类型时,需提供对应的消息打包函数。
error(msg) 向 log 服务发送一条消息。
launch(name, ...) 直接启动一个 C 服务.

register(name) 给当前服务起一个字符串名。
timeout(time, func) 设定一个定时触发函数 func ,在 time * 0.01s 后触发。
init_service(func) 用 func 函数初始化服务。
void luaL_checktype (lua_State *L, int arg, int t);

检查函数的第 arg 个参数的类型是否是 t。 参见 lua_type 查阅类型 t 的编码。

若参数endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr返回;若参数endptr为NULL,则会不返回非法字符串。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: