第二次接触Lua

关于与Lua的第一次接触应该是去年,由 于那时我一直想开发Android游戏,于是上网找各种资料看,于是便知道了Lua这个语言。但那时只是停留在空想阶段,并没实际实际学下去。现在在广州这边面试工作后,对比别人的能力和自己的水平,知识量,真是感觉逝者如斯夫的感叹啊。还是废话少扯,进入正题。

--[[传说的Hello word]]
print ("hello word");

--[[测试整型Number]]
a=1;
a1=3;
print (a+a1);


--[[字符串]]
b="hei girl"
print(b);


--[[布尔值]]
c=true;
print (c);

--[[类似JAVA的 NULL]]
c=nil;
print (c);

--[[函数,方法]]
f= function()
str="this is function"
return str
end
print (f())

--[[关联数组,这个牛啊,不同数据类型的集合,功能和JAVA的对象相似?]]

t={"first",2,true,}

for i=0,10,1 do print (i) ;end

for key,value in ipairs(t)

do
print(value);

end


感想:很灵活的动态脚本~~

先看效果: https://renmaiwang.cn/s/jkhfz Hue系列产品将具备高度的个性化定制能力,并且借助内置红、蓝、绿三原色LED的灯泡,能够混合生成1600万种不同色彩的灯光。 整个操作流程完全由安装于iPhone上的应用程序进行管理。 这一创新举措为智能照明控制领域带来了新的启示,国内相关领域的从业者也积极投身于相关研究。 鉴于Hue产品采用WiFi无线连接方式,而国内WiFi网络尚未全面覆盖,本研究选择应用更为普及的蓝牙技术,通过手机蓝牙与单片机进行数据交互,进而产生可调节占空比的PWM信号,以此来控制LED驱动电路,实现LED的调光功能以及DIY调色方案。 本文重点阐述了一种基于手机蓝牙通信的LED灯设计方案,该方案受到飞利浦Hue智能灯泡的启发,但考虑到国内WiFi网络的覆盖限制,故而选用更为通用的蓝牙技术。 以下为相关技术细节的详尽介绍:1. **智能照明控制系统**:智能照明控制系统允许用户借助手机应用程序实现远程控制照明设备,提供个性化的调光及色彩调整功能。 飞利浦Hue作为行业领先者,通过红、蓝、绿三原色LED的混合,能够呈现1600万种颜色,实现了全面的定制化体验。 2. **蓝牙通信技术**:蓝牙技术是一种低成本、短距离的无线传输方案,工作于2.4GHz ISM频段,具备即插即用和强抗干扰能力。 蓝牙协议栈由硬件层和软件层构成,提供通用访问Profile、服务发现应用Profile以及串口Profiles等丰富功能,确保不同设备间的良好互操作性。 3. **脉冲宽度调制调光**:脉冲宽度调制(PWM)是一种高效能的调光方式,通过调节脉冲宽度来控制LED的亮度。 当PWM频率超过200Hz时,人眼无法察觉明显的闪烁现象。 占空比指的...
<think>我们首先需要理解用户的问题:用户想获取lua_pcall的使用方法。根据之前的对话历史,用户已经接触过一些lua_pcall的零散信息,现在希望系统地了解其使用方法。 结合引用[1]和引用[2]中的信息,我们可以总结出lua_pcall的基本使用方法和注意事项。此外,引用[3]中提到了一个常见的错误情况(尝试调用nil值)以及解决方法(需要打开基础库)。 因此,我们应当从以下几个方面进行说明: 1. lua_pcall的功能:用于调用Lua函数(或执行Lua代码块)。 2. 函数原型:`int lua_pcall(lua_State *L, int nargs, int nresults, int msgh);` 3. 参数解释: - `L`:Lua状态机 - `nargs`:传递给函数的参数个数 - `nresults`:期望的结果个数 - `msgh`:错误处理函数的索引(0表示没有错误处理函数) 4. 返回值:成功返回0,失败返回非零错误码(如LUA_ERRRUN等)。 5. 栈变化:调用前,函数和参数应该在栈上(函数在参数下面);调用后,函数和参数被弹出,结果被压入栈(如果有结果)。如果发生错误,错误信息被压入栈顶。 6. 错误处理:调用后可以通过栈顶获取错误信息,使用`lua_tostring(L, -1)`。 7. 常见问题:比如函数未定义(尝试调用nil值)等,以及如何解决(确保库已打开,函数存在)。 同时,注意用户之前的问题中有一个代码片段(引用[2]),其中有两处lua_pcall调用: 第一次:`lua_pcall(L, 0, 0, 0);` // 执行加载的Lua文件(test.lua第二次:`lua_getglobal(L, "printmsg"); lua_pcall(L, 0, 0, 0);` // 调用Lua函数printmsg 我们可以用这个例子来具体说明。 另外,引用[3]中提到的问题是因为print函数在基础库中,所以需要调用`luaopen_base`来打开基础库。但通常我们使用`luaL_openlibs`已经打开了所有标准库,所以一般不会出现。但如果只打开了部分库,就可能出现。 因此,在回答中,我们将按照以下结构: 1. 函数原型和参数说明 2. 详细步骤(包括栈的准备和清理) 3. 返回值处理 4. 错误处理 5. 示例代码解析(结合用户提供的代码) 6. 常见错误及解决方法 最后,生成相关问题。 </think> ### `lua_pcall` 函数使用指南 #### 1. **函数原型与参数** ```c int lua_pcall(lua_State *L, int nargs, int nresults, int msgh); ``` | 参数 | 作用描述 | |-----------|--------------------------------------------------------------------------| | `L` | Lua 状态机指针 | | `nargs` | 传递给函数的参数数量(需预先压入栈) | | `nresults`| 期望接收的返回值数量 | | `msgh` | 错误处理函数在栈中的索引(0 表示无错误处理) | #### 2. **调用流程详解** 1. **准备阶段**: - 将被调函数压入栈顶 - 按顺序压入函数参数(共 `nargs` 个) ```c lua_getglobal(L, "my_func"); // 函数压栈 lua_pushinteger(L, 10); // 参数1 lua_pushstring(L, "arg2"); // 参数2 ``` 2. **执行调用**: ```c int status = lua_pcall(L, 2, 1, 0); // 2参数, 1返回值, 无错误处理 ``` 3. **结果处理**: - 成功时(`status == 0`): - 函数和参数从栈中移除 - 返回值按顺序压入栈顶(数量 = `nresults`) ``` 栈状态: [返回值1] ``` - 失败时(`status ≠ 0`): - 错误信息压入栈顶 - 可通过 `lua_tostring(L, -1)` 获取 #### 3. **错误处理模式** | `msgh` 值 | 处理方式 | |-----------|--------------------------------------------------------------------------| | `0` | 无处理,错误信息直接入栈 | | `非0` | 使用栈中索引为 `msgh` 的函数处理错误(需提前压入错误处理函数) | **错误处理示例**: ```c lua_getglobal(L, "error_handler"); // 错误处理函数压栈 lua_getglobal(L, "risky_func"); // 目标函数压栈 lua_pushinteger(L, 42); int status = lua_pcall(L, 1, 0, -2); // msgh=-2 指向错误处理函数 ``` #### 4. **关键特性** 1. **栈清理机制**: - 始终移除函数和所有参数 - 成功时按 `nresults` 压入返回值 - 失败时压入错误信息(覆盖原栈内容) 2. **常见错误码**: | 返回值常量 | 值 | 含义 | |------------------|----|--------------------------| | `LUA_OK` | 0 | 执行成功 | | `LUA_ERRRUN` | 2 | 运行时错误(如 nil 调用)| | `LUA_ERRMEM` | 4 | 内存分配失败 | | `LUA_ERRERR` | 5 | 错误处理函数自身出错 | 3. **资源管理**: - 必须检查返回值 - 错误信息需手动弹出避免栈泄漏: ```c if (status != LUA_OK) { const char* err = lua_tostring(L, -1); printf("ERROR: %s\n", err); lua_pop(L, 1); // 清除错误信息 } ``` #### 5. **完整示例** ```c #include <lua.h> #include <lauxlib.h> #include <lualib.h> int main() { lua_State* L = luaL_newstate(); luaL_openlibs(L); // 加载标准库[^3] // 加载Lua脚本 if (luaL_loadfile(L, "script.lua")) { fprintf(stderr, "Load error: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); return 1; } // 执行脚本初始化 if (lua_pcall(L, 0, 0, 0)) { // 无参数/返回值 fprintf(stderr, "Init error: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); return 1; } // 调用Lua函数 lua_getglobal(L, "calculate"); lua_pushnumber(L, 5.0); lua_pushnumber(L, 3.0); if (lua_pcall(L, 2, 1, 0)) { // 2参数, 1返回值 fprintf(stderr, "Call error: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); } else { double result = lua_tonumber(L, -1); printf("Result: %.2f\n", result); lua_pop(L, 1); // 清除返回值 } lua_close(L); return 0; } ``` #### 6. **常见问题解决** 1. **"attempt to call a nil value"**: - 原因:函数未定义(如未加载基础库) - 解决:调用 `luaL_openlibs(L)` 确保加载标准库[^3] 2. **栈不平衡**: - 现象:后续操作崩溃 - 预防:每次调用后检查返回值并清理栈 3. **错误处理函数不触发**: - 检查 `msgh` 索引是否有效 - 确保错误处理函数本身无错误 ### 相关问题 1. `lua_pcall` 和 `lua_call` 有哪些关键区别? 2. 如何通过 `lua_pcall` 捕获 Lua 中的异常? 3. 多返回值场景下如何处理 `lua_pcall` 的结果? 4. 为什么调用 Lua 函数前需要执行 `luaL_loadfile`? 5. `lua_pcall` 的 `msgh` 参数有哪些高级用法?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值