添加自定义函数(急速版)
# 添加自定义函数(急速版)
你是否有这样的困扰?
* 有个C实现的算法, 怎么搞到LuatOS里
* 我只想添加个函数, LuatOS的代码好多怎么搞?
本文以air101/air103为例, 介绍如何自行添加函数,供lua代码调用
## 预备知识
* 少许vscode经验, 基础的C语言编程能力
* 能编译已有代码, 例如air101/air103, 如果还不能, 先看看[编译教程](compile/Air101.md)
* 最好懂一点git的基本操作
## 预期效果
```lua
local ok, msg = sayhi("wendal", 18)
log.info("custom", ok, msg) -- 打印true/false和一段话
```
## 新建c文件,存放示例代码
1. 使用vscode, 打开air101/air103的源码目录
2. 导航到app/custom目录, 新建一个文件 `myapi.c`
3. 贴入以下内容
```c
//-------------------
// LuatOS的头文件, 位于LuatOS库的luat/include
#include "luat_base.h" // 基础函数
#include "luat_malloc.h" // 内存分配函数
#define LUAT_LOG_TAG "custom"
#include "luat_log.h" // 日志函数,配套LUAT_LOG_TAG
// -------------------
// 需要用的头文件,自行导入
//#include "xxx.h"
// -------------------
// 函数原型 int $name(lua_State *L)
// int 返回值的数量, 指的是从lua的堆栈中弹出多少个值作为返回值
// C函数原型只有一个参数, 对应的lua参数在lua的虚拟栈内
static int luat_custom_sayhi(lua_State *L) { // static不是必须的, 但推荐添加.
size_t len;
const char* name = luaL_checklstring(L, 1, &len); // 对应lua调用的第一个参数, "wendal"
int age = luaL_checkinteger(L, 2); // 对应lua调用的第二个参数,数值123
// age小于19的话, 就是"正确年龄"
if (age < 19) {
// 往lua堆栈压入2个返回值
lua_pushboolean(L, 1); // 压入 true
lua_pushfstring(L, "%s's age is %d", name, age); // 年龄正确!!!
}
// 否则, 当前是"错误年龄了"
else {
// 往lua堆栈压入2个返回值
lua_pushboolean(L, 1); // 压入false
lua_pushfstring(L, "%s's age is 18, always!!", name); // 不, wendal只有18岁
}
return 2; // 这里是返回值的数量, 而非 0/1 等正确/错误返回码.
}
void luat_custom_init(lua_State *L) { // 函数声明在luat_base.h里
LLOGD("custom init begin ...");
// 添加全局函数, 函数名就叫sayhi吧
lua_pushcfunction(L, luat_custom_sayhi); // 先压入堆栈
lua_setglobal(L, "sayhi"); // 压入_G.sayhi = XXX
LLOGD("custom init done");
return; // 暂不需要返回值.
}
```
## 启用自定义函数构造
1. 打开 `app/include/luat_conf_bsp.h`
2. 在中间的位置, 添加以下宏定义
```c
#define LUAT_HAS_CUSTOM_LIB_INIT 1
```
## 愉快地测试
1. 执行xmake, 常规编译一下
2. 刷机,下脚本,看效果
```log
你来填 ^_^
```
* 编译失败? 根据提示修正语法错误
* 刷机后提示找不到`sayhi` -- 确保编译正确, 确保选择了正确的底层固件文件, 确保刷入了新的底层
## 搞不定? 求帮助? 到QQ群求助或者gitee发帖
1. QQ群: 1061642968
2. gitee: https://gitee.com/openLuat/LuatOS 顺便点个star, 谢谢
## 拓展1-- 函数比较多, 我想做成一个库可以吗?
必须可以呀
* 先给库起个酷炫的名字
* 仿造已有的`luat_lib_xxx.c` 写一个库
* 最初建议只写1个函数, 声明好`rotable_Reg`和`luaopen_xxx`方法
* 在 `custom_init` 里调用 `luaopen_xxx` 方法即可
## 拓展2 -- 添加静态库进行链接
* 需要一点点xmake知识了, 但搜索字符串添加也可以
* 把a文件放入lib目录, 假设名字叫 `libcool.a`
* 修改`xmake.lua`, 寻找 ` ./lib/libgt.a `
* 在其之前或之后, 添加 ` ./lib/libcool.a ` , 注意前后空格
* 愉快地编译