当前位置: 首页 > ai >正文

Lua 基础 API与 辅助库函数 中关于创建的方法用法

目录

  • 基础 API 函数
    • 1. `lua_len(L, index)`
    • 2. `lua_load(L, reader, data, chunkname, mode)`
    • 3. `lua_newstate(allocator, ud)`
    • 4. `lua_newtable(L)`
    • 5. `lua_newthread(L)`
    • 6. `lua_newuserdata(L, size)`
    • 7. `lua_next(L, index)`
  • 辅助库函数(`luaL_*`)
    • 8. `luaL_len(L, index)`
    • 9. `luaL_loadbuffer(L, buff, sz, name)`
    • 10. `luaL_loadbufferx`
    • 11. `luaL_loadfile`
    • 12. `luaL_loadfilex`
    • 13. `luaL_loadstring`
    • 14. `luaL_newlib`
    • 15. `luaL_newlibtable`
    • 16. `luaL_newmetatable`
  • 关键整合示例
    • 用户数据与元表
    • 协程调度
  • 总结


基础 API 函数

1. lua_len(L, index)

  • 作用:获取指定索引处值的长度(类似 # 操作符),结果压入栈顶。
  • 参数L(Lua 状态机),index(目标值的栈位置)。
  • 代码示例
    lua_pushstring(L, "Hello"); // 压入字符串
    lua_len(L, -1);            // 计算长度(结果为5)
    printf("Length: %lld\n", lua_tointeger(L, -1)); // 输出5
    lua_pop(L, 2);             // 清理栈(字符串和长度)
    

2. lua_load(L, reader, data, chunkname, mode)

  • 作用:加载 Lua 代码块但不执行,需配合 lua_pcall
  • 参数reader(读取函数),data(用户数据),chunkname(调试名),mode(加载模式)。
  • 代码示例
    const char *code = "return 42";
    lua_Reader reader = [](lua_State *L, void *data, size_t *size) {static int read = 0;if (!read) {*size = strlen((const char*)data);read = 1;return data;}return (const char*)NULL;
    };
    if (lua_load(L, reader, (void*)code, "chunk", "t") == LUA_OK) {lua_pcall(L, 0, 1, 0); // 执行代码,返回42printf("Result: %d\n", (int)lua_tointeger(L, -1));
    }
    

3. lua_newstate(allocator, ud)

  • 作用:创建独立 Lua 虚拟机,允许自定义内存分配。
  • 参数allocator(内存分配函数),ud(用户数据)。
  • 代码示例
    void* custom_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {if (nsize == 0) { free(ptr); return NULL; }return realloc(ptr, nsize);
    }
    lua_State *L = lua_newstate(custom_alloc, NULL); // 创建新状态
    lua_close(L); // 关闭
    

4. lua_newtable(L)

  • 作用:创建空表并压入栈顶。
  • 代码示例
    lua_newtable(L);                  // 创建新表
    lua_pushstring(L, "value");       // 键为 "key"
    lua_pushinteger(L, 100);          // 值 100
    lua_settable(L, -3);              // 表[-3] 设置键值对
    lua_setglobal(L, "my_table");     // 设为全局变量
    

5. lua_newthread(L)

  • 作用:创建新协程,返回其 lua_State
  • 代码示例
    lua_State *co = lua_newthread(L); // 创建协程
    lua_pushstring(co, "coroutine");  // 协程独立栈
    lua_resume(co, L, 0);             // 启动协程(需提前加载函数)
    

6. lua_newuserdata(L, size)

  • 作用:分配用户数据内存并压入栈顶。
  • 代码示例
    typedef struct { int x; } MyData;
    MyData *data = (MyData*)lua_newuserdata(L, sizeof(MyData));
    data->x = 10; // 初始化
    // 绑定元表
    luaL_getmetatable(L, "MyData");
    lua_setmetatable(L, -2);
    

7. lua_next(L, index)

  • 作用:遍历表的键值对。
  • 代码示例
    lua_getglobal(L, "my_table"); // 获取表
    lua_pushnil(L);               // 初始键
    while (lua_next(L, -2)) {     // 遍历printf("Key: %s, Value: %s\n",lua_tostring(L, -2),lua_tostring(L, -1));lua_pop(L, 1);           // 移除值,保留键
    }
    

辅助库函数(luaL_*

8. luaL_len(L, index)

  • 作用:直接返回值的长度(整数)。
  • 代码示例
    lua_pushstring(L, "Lua"); 
    lua_Integer len = luaL_len(L, -1); // len = 3
    

9. luaL_loadbuffer(L, buff, sz, name)

  • 作用:从内存加载代码。
  • 代码示例
    const char *code = "print('Hello from buffer!')";
    if (luaL_loadbuffer(L, code, strlen(code), "buffer") == LUA_OK) {lua_pcall(L, 0, 0, 0); // 输出 Hello from buffer!
    }
    

10. luaL_loadbufferx

  • 作用:同 luaL_loadbuffer,支持模式(如二进制)。
  • 代码示例
    luaL_loadbufferx(L, code, size, "chunk", "b"); // 加载二进制块
    

11. luaL_loadfile

  • 作用:加载文件中的代码。
  • 代码示例
    if (luaL_loadfile(L, "script.lua") == LUA_OK) {lua_pcall(L, 0, 0, 0); // 执行文件
    }
    

12. luaL_loadfilex

  • 作用:支持指定加载模式的文件加载。
  • 代码示例
    luaL_loadfilex(L, "precompiled.luac", "b"); // 加载二进制文件
    

13. luaL_loadstring

  • 作用:从字符串加载代码。
  • 代码示例
    luaL_loadstring(L, "return 1 + 1");
    lua_pcall(L, 0, 1, 0); // 返回2
    

14. luaL_newlib

  • 作用:创建并注册库函数表。
  • 代码示例
    static const luaL_Reg mylib[] = {{"add", [](lua_State *L) { int a = luaL_checkinteger(L, 1);int b = luaL_checkinteger(L, 2);lua_pushinteger(L, a + b);return 1;}},{NULL, NULL}
    };
    luaL_newlib(L, mylib);        // 创建表并注册函数
    lua_setglobal(L, "mylib");    // 全局名为 mylib
    

15. luaL_newlibtable

  • 作用:创建空表供后续填充。
  • 代码示例
    luaL_newlibtable(L, mylib);   // 仅创建空表
    luaL_setfuncs(L, mylib, 0);   // 手动注册函数
    

16. luaL_newmetatable

  • 作用:创建或获取元表。
  • 代码示例
    if (luaL_newmetatable(L, "MyType")) { // 新建元表lua_pushcfunction(L, [](lua_State *L) { // __gc 方法MyData *d = (MyData*)lua_touserdata(L, 1);free(d); // 清理资源return 0;});lua_setfield(L, -2, "__gc"); // 设置元方法
    }
    

关键整合示例

用户数据与元表

// 定义类型
typedef struct { int val; } MyType;// 元表方法
static const luaL_Reg mytype_methods[] = {{"get", [](lua_State *L) {MyType *mt = (MyType*)luaL_checkudata(L, 1, "MyType");lua_pushinteger(L, mt->val);return 1;}},{NULL, NULL}
};// 注册类型
int luaopen_mytype(lua_State *L) {luaL_newmetatable(L, "MyType");      // 创建元表luaL_newlib(L, mytype_methods);      // 注册方法lua_setfield(L, -2, "__index");      // 元表.__index = 方法表lua_pushcfunction(L, [](lua_State *L) { // 构造函数MyType *mt = (MyType*)lua_newuserdata(L, sizeof(MyType));mt->val = luaL_checkinteger(L, 1);luaL_getmetatable(L, "MyType");lua_setmetatable(L, -2);return 1;});return 1;
}

协程调度

lua_State *co = lua_newthread(L);        // 创建协程
luaL_loadstring(co, "coroutine.yield(1); coroutine.yield(2)"); // 加载代码
int res;
do {res = lua_resume(co, L, 0);          // 恢复执行printf("Yielded: %d\n", lua_tointeger(co, -1));
} while (res == LUA_YIELD);

总结

  • 虚拟机管理lua_newstate 创建独立环境,需手动管理内存。
  • 数据操作lua_newtablelua_newuserdata 结合元表实现复杂结构。
  • 代码加载luaL_load* 系列加载代码,需显式调用 lua_pcall 执行。
  • 协程lua_newthread 创建轻量级线程,通过 lua_resume 控制执行。

正确使用这些函数能高效嵌入 Lua 到 C/C++ 项目中,实现灵活的脚本扩展。

http://www.xdnf.cn/news/3583.html

相关文章:

  • 基于STM32的智能摇头风扇设计(WIFI+语音控制)
  • CGAL:最小包围圆
  • 共铸价值:RWA 联合曲线价值模型,撬动现实资产生态
  • 基于机器学习的心脏病数据分析与可视化(百度智能云千帆AI+DeepSeek人工智能+机器学习)健康预测、风险评估与数据可视化 健康管理平台 数据分析与处理
  • k8s 探针
  • 基于ArduinoIDE的任意型号单片机 + GPS北斗BDS卫星定位
  • 基于「骑手外卖系统」串联7大设计原则
  • 【Hot 100】 146. LRU 缓存
  • Three.js在vue中的使用(二)-加载、控制
  • 【ICMP协议深度解析】从网络诊断到安全实践
  • Mysql常用语句汇总
  • centos7.0无法安装php8.2/8.3
  • ROS2学习笔记|创建工作空间并打印文件内容
  • 视频编解码学习二之颜色科学
  • UDP / TCP 协议
  • 使用DeepSeek协助恢复历史数据
  • GoFrame 奉孝学习笔记
  • ElasticSearch深入解析(十):字段膨胀(Mapping 爆炸)问题的解决思路
  • leetcode0096. 不同的二叉搜索树-medium
  • 从零开发一个B站视频数据统计Chrome插件
  • Android Compose 层叠布局(ZStack、Surface)源码深度剖析(14)
  • AI Agent开发第48课-DIFY中利用AI动态判断下一步流程-DIFY调用API、REDIS、LLM
  • 面试现场“震”情百态:HashMap扩容记
  • 昇腾的CANN是什么?跟英伟达CUDA的有什么联系和区别?【浅谈版】
  • 生成式 AI 的未来
  • [一文解决大模型微调+部署+RAG] LLamaFactory微调模型后使用Ollama + RAGFlow在Windows本地部署
  • LabVIEW软件设计锂电池故障模拟检测
  • 学习黑客安全基础理论入门
  • 深度学习经典网络之LeNet-5详解
  • 【AI面试准备】电商购物车AI测试设计与实施