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

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++ 项目中,实现灵活的脚本扩展。

相关文章:

  • python中的yield关键字用法
  • 【Mytais系列】Type模块:类型转换
  • VBA 64位API声明语句第009讲
  • RUST变量学习笔记
  • 【AI面试准备】XMind拆解业务场景识别AI赋能点
  • 2025年渗透测试面试题总结-拷打题库36(题目+回答)
  • 迭代器的思想和实现细节
  • 【计算机视觉】三维重建: OpenMVS:工业级多视图立体视觉重建框架
  • 腾讯混元-DiT 文生图
  • 基于Jenkins的DevOps工程实践之Jenkins共享库
  • Python 数据智能实战 (10):智能商品推荐 - LLM “猜你喜欢”
  • ES6语法
  • 驱动精灵v9.7(含网卡版)驱动工具软件下载及安装教程
  • MySQL 日期加减函数详解
  • 进程间通信(IPC)
  • sql 注入中的万能密码
  • iOS启动优化:从原理到实践
  • ActiveMQ 集群搭建与高可用方案设计(二)
  • 大数据:数字时代的驱动力
  • 数据库原理与应用实验二 题目七
  • 过半中国上市公司去年都在“扩编”,哪些公司人效最高
  • 央行行长详解降准:将释放长期流动性1万亿,整体存款准备金率平均水平降至6.2%
  • 专家解读《人源类器官研究伦理指引》:构建类器官研究全过程伦理治理框架
  • 长三角9座“万亿城市”一季报出炉:多地机器人产量大增
  • 新闻1+1丨多地政府食堂开放“舌尖上的服务”,反映出怎样的理念转变?
  • 新闻1+1丨多地政府食堂开放 “舌尖上的服务”,反映出怎样的理念转变?