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

[复制链接]
发表于 2025-9-18 01:35:04 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
更多信息 进群了解
QQ群:756167961

  


底子 API 函数

1. lua_len(L, index)



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



  • 作用:加载 Lua 代码块但不实行,需共同 lua_pcall。
  • 参数:reader(读取函数),data(用户数据),chunkname(调试名),mode(加载模式)。
  • 代码示例:
    1. const char *code = "return 42";
    2. lua_Reader reader = [](lua_State *L, void *data, size_t *size) {
    3.     static int read = 0;
    4.     if (!read) {
    5.         *size = strlen((const char*)data);
    6.         read = 1;
    7.         return data;
    8.     }
    9.     return (const char*)NULL;
    10. };
    11. if (lua_load(L, reader, (void*)code, "chunk", "t") == LUA_OK) {
    12.     lua_pcall(L, 0, 1, 0); // 执行代码,返回42
    13.     printf("Result: %d\n", (int)lua_tointeger(L, -1));
    14. }
    复制代码
3. lua_newstate(allocator, ud)



  • 作用:创建独立 Lua 假造机,允许自界说内存分配。
  • 参数:allocator(内存分配函数),ud(用户数据)。
  • 代码示例:
    1. void* custom_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
    2.     if (nsize == 0) { free(ptr); return NULL; }
    3.     return realloc(ptr, nsize);
    4. }
    5. lua_State *L = lua_newstate(custom_alloc, NULL); // 创建新状态
    6. lua_close(L); // 关闭
    复制代码
4. lua_newtable(L)



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



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



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



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

辅助库函数(luaL_*)

8. luaL_len(L, index)



  • 作用:直接返回值的长度(整数)。
  • 代码示例:
    1. lua_pushstring(L, "Lua");
    2. lua_Integer len = luaL_len(L, -1); // len = 3
    复制代码
9. luaL_loadbuffer(L, buff, sz, name)



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



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



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



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



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



  • 作用:创建并注册库函数表。
  • 代码示例:
    1. static const luaL_Reg mylib[] = {
    2.     {"add", [](lua_State *L) {
    3.         int a = luaL_checkinteger(L, 1);
    4.         int b = luaL_checkinteger(L, 2);
    5.         lua_pushinteger(L, a + b);
    6.         return 1;
    7.     }},
    8.     {NULL, NULL}
    9. };
    10. luaL_newlib(L, mylib);        // 创建表并注册函数
    11. lua_setglobal(L, "mylib");    // 全局名为 mylib
    复制代码
15. luaL_newlibtable



  • 作用:创建空表供后续添补。
  • 代码示例:
    1. luaL_newlibtable(L, mylib);   // 仅创建空表
    2. luaL_setfuncs(L, mylib, 0);   // 手动注册函数
    复制代码
16. luaL_newmetatable



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

关键整合示例

用户数据与元表

  1. // 定义类型
  2. typedef struct { int val; } MyType;
  3. // 元表方法
  4. static const luaL_Reg mytype_methods[] = {
  5.     {"get", [](lua_State *L) {
  6.         MyType *mt = (MyType*)luaL_checkudata(L, 1, "MyType");
  7.         lua_pushinteger(L, mt->val);
  8.         return 1;
  9.     }},
  10.     {NULL, NULL}
  11. };
  12. // 注册类型
  13. int luaopen_mytype(lua_State *L) {
  14.     luaL_newmetatable(L, "MyType");      // 创建元表
  15.     luaL_newlib(L, mytype_methods);      // 注册方法
  16.     lua_setfield(L, -2, "__index");      // 元表.__index = 方法表
  17.     lua_pushcfunction(L, [](lua_State *L) { // 构造函数
  18.         MyType *mt = (MyType*)lua_newuserdata(L, sizeof(MyType));
  19.         mt->val = luaL_checkinteger(L, 1);
  20.         luaL_getmetatable(L, "MyType");
  21.         lua_setmetatable(L, -2);
  22.         return 1;
  23.     });
  24.     return 1;
  25. }
复制代码
协程调治

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

总结



  • 假造机管理:lua_newstate 创建独立环境,需手动管理内存。
  • 数据操纵:lua_newtable、lua_newuserdata 团结元表实现复杂结构。
  • 代码加载:luaL_load* 系列加载代码,需显式调用 lua_pcall 实行。
  • 协程:lua_newthread 创建轻量级线程,通过 lua_resume 控制实行。
正确利用这些函数能高效嵌入 Lua 到 C/C++ 项目中,实现机动的脚本扩展。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表