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


基础 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); // 执行代码,返回42
        printf("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++ 项目中,实现灵活的脚本扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值