Skynet服务器框架(七) Lua中调用自定义C库
来源:互联网 发布:java patternlayout 编辑:程序博客网 时间:2024/06/07 13:41
引言:
在skynet中,我们通常使用lua来写业务层的逻辑,并且每个功能模块基本上就是一个运行在沙盒中的lua服务。但是,当需要我们需要开发拓展的库或者进行高性能要求的模块开发时,还是需要考虑在C语言层面来开发一个动态库(.so),并提供可以在lua中调用的接口,然后再lua中调用此C库。
自定义C库:
查看了Lua官方的关于如何注册C库(C Libraries)的内容,其中有一段如下:
When you extend Lua with C functions, it is a good idea to design your code as a C library, even when you want to register only one C function: Sooner or later (usually sooner) you will need other functions. As usual, the auxiliary library offers a helper function for this job. The luaL_openlib function receives a list of C functions and their respective names and registers all of them inside a table with the library name.
大致的意思就是:当我们要使用c语言的功能函数来拓展Lua的功能时,将这些函数封装成一个C库是一个不错的选择。
1.动态库的标准:
根据官方的引导,定义一个C库的时候,在定义可以被调用的方法时与普通的C语言定义方式并无差别,只是需要额外添加一个数组和一个方法:
定义一个测试函数:
static int l_dir (lua_State *L) { ... /* as before */}
声明一个
luaL_reg
类型的数组:static const struct luaL_reg mylib [] = { {"dir", l_dir}, {NULL, NULL} /* sentinel */};
这个数组的每个item都相当于一个
key-value
结构,包含两个属性{"(lua调用时使用的函数名)",C定义函数名(函数指针)}
,这个数组就是用来指定此C库的各个函数以及他们在lua中被调用时对应使用的接口名称(注意:最后一个item必须是{NULL, NULL}
,不可缺少)。定义一个
luaopen_*
函数,并调用luaL_openlib
函数:int luaopen_mylib (lua_State *L) { luaL_openlib(L, "mylib", mylib, 0); return 1;}
这个函数相当于作为此库的main函数。注意此函数的名称规则:
luaopen_
是此函数的前缀,不可修改;- 后面的内容是我们在lua中使用
require
引用此库时的字符串名称(假如名称中带有“”,在使用require
需要将“”替换为“.”,例如:“mylib_test”->“mylib.test”)。
在Lua5.0中调用的是
luaL_openlib
,但是在Lua5.3中,则是使用luaL_newlib
2.创建测试C库:
根据上述的定制标准,这里我们就来自定义一个自己C库,首先创建一个.c的文件,例如“mylib.c”,写几个测试方法:
#include <lua.h> #include <lauxlib.h> #include <stdio.h> static int mtest1(lua_State *L){ printf("--- mtest1\n"); return 0; } static int mtest2(lua_State *L){ //从传入参数table中获取第1个参数,转为整型 int num = luaL_checkinteger(L,1); printf("--- mtest2:num=%d\n",num); return 0; } int luaopen_mylib(lua_State *L){ luaL_Reg l[] = { {"test1",mtest1}, {"test2",mtest2}, {NULL,NULL} }; luaL_newlib(L,l); return 1; }
3.C库打包:
这里我使用在Linux环境下进行 C库的编译
和 lua引用测试的执行
,而且使用gnu make
来作为构建工具,关于如何编写Makefile文件,这里就不做赘述了,做后端开发的话,特别是C++/C,还是应该学一下的。推荐教程:Linux下编写 makefile 详细教程
创建Makefile:
C语言文件类打包成动态库使用过Makefile来进行编译完成的,这里我们就根据我们创建的C源码文件来创建一个对应Makefile文件。CC ?= gcc CFLAGS = -g -O2 -Wall -I$(LUA_INC) SHARED := -fPIC --shared TARGET = myLualib.so LUA_CLIB_PATH = ./#引入lua头文件(根据你安装Lua库时的目录而定)LUA_INC ?= /usr/local/src/lua-5.3.0/srcstart: $(TARGET) $(TARGET) : ./test.c $(CC) $(CFLAGS) $(SHARED) $^ -o $@ clean: rm -fr $(TARGET) $(LUA_CLIB_PATH) : mkdir $(LUA_CLIB_PATH)
执行打包指令:
make
执行输出:
root@ubuntu:/application/tests# lsMakefile test.c test.luaroot@ubuntu:/application/tests# makecc -g -Wall -I/usr/local/src/lua-5.3.0/src -fPIC --shared test.c -o mylib.soroot@ubuntu:/application/tests# lsMakefile mylib.so test.c test.lua
也可以直接执行如下指令进行编译:
gcc -g -Wall -I/usr/local/src/lua-5.3.0/src --shared -fPIC -o mylib.so ./test.c
执行编译的结果是我们能得到一个 mylib.so
动态库文件,那么接下来我们就要尝试在lua中引入此C库并调用其中的方法。
以上指令都需要在root权限下进行执行,假如当前不是root权限,需要输入
sudo su
进行切换。
lua中调用动态库接口:
新建一个测试的lua脚本,我这里取名为 test.lua
:
1.动态库引入:
--设置.so搜寻路劲package.cpath = "./?.so" --加载我们自定义的库mylib.solocal mylib = require "mylib";
2.动态库调用:
--调用C库中的测试方法mylib.test1()mylib.test2(666)
3.运行测试脚本:
lua test.lua
输出执行结果如下:
root@ubuntu:/application/tests# lsMakefile mylib.so test.c test.luaroot@ubuntu:/application/tests# lua test.lua--- mtest1--- mtest2:num=666
小结:
参考以上的步骤,以后我们就能够根据自己需要构建功能C库,然后导入到lua中进行使用,在使用skynet框架是尤为重要的技能。(发现了还有一个精简版的skynet,叫做hive)
参考资料:
- Linux环境下 lua 调用自定义so动态库(skynet)
- lua 加载C动态库
- lua动态链接库(luaopen_*函数的使用)
- 快速掌握Lua 5.3 —— 编写提供给Lua使用的C库函数的技巧 (1)
- Skynet服务器框架(七) Lua中调用自定义C库
- Linux环境下 lua 调用自定义so动态库(skynet)
- Linux环境下 lua 调用自定义so动态库(skynet)
- skynet学习0:c调用lua
- skynet学习0:lua调用c
- Skynet服务器框架(二) C源码剖析启动流程
- Skynet服务器框架(四) Lua服务创建和启动剖析
- Skynet服务器框架(九) snax框架
- Skynet服务器框架(九) snax框架
- Lua 调用自定义C模块(练习)
- skynet源码分析(9)--LUA C API
- Lua 调用自定义C模块
- Lua 调用自定义C模块
- lua中调用C
- LUA中调用C
- Skynet服务器框架(三) Mac OS X环境安装
- Skynet服务器框架(五) 使用pbc(protobuf)
- Skynet服务器框架(八) 任务和消息调度机制
- 百度如何能实时检索到15分钟前新生成的网页?
- 1021. 个位数统计
- Android拍照扫描识别身份证信息SDK
- 第20节:Scala 提取器与注解深度解析之编程进阶
- 复习JQ (8)
- Skynet服务器框架(七) Lua中调用自定义C库
- Spark存储管理(读书笔记)
- 测试
- linux下c语言-day7
- 关闭光猫DHCP服务器后无法打开光猫登录页面
- git实用操作
- Java 访问权限控制
- LeetCode#21. Merge Two Sorted Lists
- LaTex中文输入