马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
更多信息 进群了解
QQ群:756167961
底子 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_newtable、lua_newuserdata 团结元表实现复杂结构。
- 代码加载:luaL_load* 系列加载代码,需显式调用 lua_pcall 实行。
- 协程:lua_newthread 创建轻量级线程,通过 lua_resume 控制实行。
正确利用这些函数能高效嵌入 Lua 到 C/C++ 项目中,实现机动的脚本扩展。
|