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会把任何不同于 false 和 nil 的值当作真返回;
否则就返回假。 (如果你想只接收真正的 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,则会不返回非法字符串。
相关文章推荐
- skynet框架应用 (三) 构建服务的基础API
- Lua 中的常用API
- 常用公共服务接口(1)天气预报API
- Skynet服务器框架(四) Lua服务创建和启动剖析
- skynet luaAPI
- skynet如何启动一个lua服务
- skynet记录7:服务(c和lua)
- skynet 常用lua函数汇总
- skynet服务的缺陷 lua死循环
- lua中string常用api
- Lua5.1的常用API
- skynet lua服务callback执行过程
- skynet源码分析(9)--LUA C API
- Lua常用API
- OpenGL 常用 API
- 玩转java多线程学习篇四 Thread类的常用API之currentThread,isAlive,sleep,interrupt,isInterrupted,stop
- 短信API服务
- ArcGIS API for JavaScript的服务查询
- 微信小程序语音识别服务搭建全过程解析(https api开放,支持新接口mp3录音、老接口silk录音)
- 高德地图web服务api--搜索功能(输入提示)