Skynet中的例子
c-lua的接口是比较重要的一部分
因为skynet底层使用的c语言,上层使用lua来实现,必然关涉到c-lua的交互
我们重点关注:skynet/lualib-src目录下的文件
在平时分析Skynet源码的时候,我们经常可以看到类似的调用
local c = require "skynet.core"
-- 这里的skynet就是在 skynet/lualib-src/lua-skynet.c 文件下实现的
-- 只不过是 skynet/lualib-src 文件下的c文件,最终都被编译到 skynet/luaclib 下
-- 详细见《Skynet源码准备》
在skynet/lualib/skynet.lua中
local c = require "skynet.core"
-- 除了一些普通的API调用
c.send()
c.error()
-- skynet还封装了一些常用的命令
-- 但是通过统一的接口来使用
c.intcommand("STAT", "mqlen")
c.command("EXIT")
-- 以上命令就能直接在lua层调用c层的函数
-- 当然这种形式最后得需要c文件编译为so库才行
而在skynet/lualib-src/lua-skynet.c中
LUAMOD_API int
luaopen_skynet_core(lua_State *L) {
luaL_checkversion(L);
luaL_Reg l[] = {
{ "send" , lsend },
{ "genid", lgenid },
{ "redirect", lredirect },
{ "command" , lcommand },
{ "intcommand", lintcommand },
{ "addresscommand", laddresscommand },
{ "error", lerror },
{ "harbor", lharbor },
{ "callback", lcallback },
{ "trace", ltrace },
{ NULL, NULL },
};
// functions without skynet_context
luaL_Reg l2[] = {
{ "tostring", ltostring },
{ "pack", luaseri_pack },
{ "unpack", luaseri_unpack },
{ "packstring", lpackstring },
{ "trash" , ltrash },
{ "now", lnow },
{ "hpc", lhpc }, // getHPCounter
{ NULL, NULL },
};
// 部分代码省略
}
// 可以看到,之前在lua层的函数调用,在c层都有一一对应的c函数实现
最终完成了c-lua的交互
其实:zlog的c-lua调用和skynet的c-lua调用也是一样的
详细见在zlog的编译脚本和文件
实际举例
//make so lib for lua.
//cc -g -O2 -Wall -fPIC --shared usertime.c -o usertime.so
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <lua.h>
#include <lauxlib.h>
//微秒
static int getmicrosecond(lua_State *L) {
struct timeval tv;
gettimeofday(&tv,NULL);
long microsecond = tv.tv_sec*1000000+tv.tv_usec;
lua_pushnumber(L, microsecond);
return 1;
}
//毫秒
static int getmillisecond(lua_State *L) {
struct timeval tv;
gettimeofday(&tv,NULL);
long millisecond = (tv.tv_sec*1000000+tv.tv_usec)/1000;
lua_pushnumber(L, millisecond);
return 1;
}
int luaopen_usertime(lua_State *L) {
luaL_checkversion(L);
luaL_Reg l[] = {
{"getmillisecond", getmillisecond},
{"getmicrosecond", getmicrosecond},
{ NULL, NULL },
};
luaL_newlib(L, l);
return 1;
}
这个文件即可以编译出一个usertime.so,放入lua的搜索路径下
在直接require “usertime”,即可以直接使用对应的函数了
参考资料
如何在 skynet 中加入 C 库 · cloudwu/skynet Wiki (github.com)