1.计算机程序开发中预定义出来的表是什么?
2.Cè¯è¨åC++çåºå«
3.软件开发中不可预期的错误有哪些解决办法呢?
4.setjmp是怎么工作的
计算机程序开发中预定义出来的表是什么?
在程序开发中预定义出来的表就是注册表。1.提供了一个 注册表, 这是一个预定义出来的表, 可以用来保存任何 C 代码想保存的 Lua 值。 这个表可以用有效伪索引 LUA_REGISTRYINDEX 来定位。 任何 C 库都可以在这张表里保存数据,mui更新源码 为了防止冲突,你需要特别小心的选择键名。 一般的用法是,你可以用一个包含你的库名的字符串做为键名, 或者取你自己 C 对象的地址,以轻量用户数据的形式做键, 还可以用你的代码创建出来的任意 Lua 对象做键。 关于变量名,字符串键名中以下划线加大写字母的名字被 Lua 保留。
2.注册表中的整数键用于引用机制 (), 以及一些预定义的jmf源码值。 因此,整数键不要用于别的目的。
3.当你创建了一个新的 Lua 状态机, 其中的注册表内就预定义好了几个值。这些预定义值可以用整数索引到, 这些整数以常数形式定义在 lua.h 中。 有下列常数:
4.LUA_RIDX_MAINTHREAD: 注册表中这个索引下是状态机的主线程。(主线程和状态机同时被创建出来。)
5.LUA_RIDX_GLOBALS: 注册表的这个索引下是全局环境。
6.在内部实现中,Lua 使用了 C 的 longjmp 机制来处理错误。(如果你使用 C++ 编译,Lua 将换成异常; 细节请在源代码中搜索 LUAI_THROW。) 当 Lua 碰到任何错误 (比如内存分配错误、类型错误、语法错误、webdriver源码还有运行时错误) 它都会 抛出一个错误出去; 也就是调用一次长跳转。 在 保护环境 下, Lua 使用 setjmp 来设置一个恢复点; 任何发生的错误都会跳转到最近的一个恢复点。
7.如果错误发生在保护环境之外,Lua 会先调用 panic 函数 () 然后调用 abort 来退出宿主程序。 你的 panic 函数只要不返回 (例如:长跳转到你在 Lua 外你自己设置的恢复点) 就可以不退出程序。
8.panic 函数以错误消息处理器()的方式运行;错误消息在栈顶。 不同的是,它不保证栈空间。 做任何压栈操作前,panic 函数都必须先检查是否有足够的空间 ()。
大多数 API 函数都有可能抛出错误, 例如在内存分配错误时就会抛出。 每个函数的文档都会注明它是否可能抛出错误。
9.在 C 函数内部,你可以通过调用 lua_error 来抛出错误。stingray 源码
Cè¯è¨åC++çåºå«
Cè¯è¨ä¸Cï¼ï¼çåºå«æå¾å¤ï¼ä¸é¢æ¯ç®è¦æ¦è¿°ï¼1ãé¢åä¸å
Cè¯è¨æ¯é¢åè¿ç¨çï¼
Cï¼ï¼æ¯é¢å对象çã
å½æ°åº
Cè¯è¨ææ åçå½æ°åºï¼å®ä»¬æ¾æ£çï¼åªæ¯æåè½ç¸åçå½æ°æ¾å¨ä¸ä¸ªå¤´æ件ä¸ï¼
Cï¼ï¼å¯¹äºå¤§å¤æ°çå½æ°é½æ¯æéæçå¾ç´§å¯ï¼ç¹å«æ¯Cè¯è¨ä¸æ²¡æçCï¼ï¼ä¸çAPIæ¯å¯¹Windowç³»ç»ç大å¤æ°APIææºçç»åï¼æ¯ä¸ä¸ªéä½ãä½ä½ ä¹å¯è½åç¬è°ç¨APIã
3ãç»ææ¦å¿µä¸å
Cè¨ä¸ç»æåªææååéï¼è没æåæ¹æ³ï¼Cè¯èå¨ä½æ¯å¨Cè¯è¨ä¸ç»æçæåæ¯å ¬å ±çï¼ä»ä¹æ³è®¿é®å®çé½å¯ä»¥è®¿é®ï¼
Cï¼ï¼ä¸ç»æä¸ï¼å®å¯ä»¥æèªå·±çæååéåæåå½æ°ã
4ãåä½æ°éä¸å
Cè¯è¨å¯ä»¥åå¾å¤æ¹é¢çç¨åºï¼
Cï¼ï¼å¯ä»¥åå¾æ´å¤æ´å¥½ï¼Cï¼ï¼å¯ä»¥ååºäºDOSçç¨åºï¼åDLLï¼åæ§ä»¶ï¼åç³»ç»ã
5ãç»ç»ä¸å
Cè¯è¨å¯¹ç¨åºçæ件çç»ç»æ¯æ¾æ£çï¼å ä¹æ¯å ¨è¦ç¨åºå¤çï¼
Cï¼ï¼å¯¹æ件çç»ç»æ¯ä»¥å·¥ç¨ï¼åæ件åç±»æç¡®ã
软件开发中不可预期的错误有哪些解决办法呢?
最常见的的解决办法就是错误一场捕获及异常处理,这也是我经常使用的一个防范。1.错误处理我们通常称为异常处理,不同语言的报错方式与形式各一,下面以一种语言解释:
在内部实现中,Lu a 使用了 C 的 longjmp 机制来处理错误。 (如果你使用 C++ 编译,L ua 将换成异常; 细节请在源代码中搜索 LUAI_THROW。) 当 Lu a 碰到任何错误 (比如内存分配错误、类型错误、语法错误、还有运行时错误) 它都会 抛出一个错误出去; 也就是调用一次长跳转。 在 保护环境 下, Lu a 使用 setjmp 来设置一个恢复点; 任何发生的错误都会跳转到最近的一个恢复点。
如果错误发生在保护环境之外, L ua 会先调用 panic 函数 然后调用 abort 来退出宿主程序。kinfu源码 你的 panic 函数只要不返回 (例如:长跳转到你在 L ua 外你自己设置的恢复点) 就可以不退出程序。
2.panic 函数以错误消息处理器的方式运行;错误消息在栈顶。 不同的是,它不保证栈空间。 做任何压栈操作前,panic 函数都必须先检查是否有足够的空间 。
大多数 API 函数都有可能抛出错误, 例如在内存分配错误时就会抛出。 每个函数的文档都会注明它是否可能抛出错误。
在 C 函数内部,你可以通过调用 lu a_error 来抛出错误。
如果错误发生在保护环境之外, L ua 会先调用 panic 函数 然后调用 abort 来退出宿主程序。 你的 panic 函数只要不返回 (例如:长跳转到你在 L ua 外你自己设置的恢复点) 就可以不退出程序。
如果错误发生在保护环境之外, L ua 会先调用 panic 函数 然后调用 abort 来退出宿主程序。 你的 panic 函数只要不返回 (例如:长跳转到你在 L ua 外你自己设置的恢复点) 就可以不退出程序。
3.错误处理我们通常称为异常处理,不同语言的报错方式与形式各一,下面以一种语言解释:
在内部实现中,Lu a 使用了 C 的 longjmp 机制来处理错误。 (如果你使用 C++ 编译,L ua 将换成异常; 细节请在源代码中搜索 LUAI_THROW。) 当 Lu a 碰到任何错误 (比如内存分配错误、类型错误、语法错误、还有运行时错误) 它都会 抛出一个错误出去; 也就是调用一次长跳转。 在 保护环境 下, Lu a 使用 setjmp 来设置一个恢复点; 任何发生的错误都会跳转到最近的一个恢复点。
如果错误发生在保护环境之外, L ua 会先调用 panic 函数 然后调用 abort 来退出宿主程序。 你的 panic 函数只要不返回 (例如:长跳转到你在 L ua 外你自己设置的恢复点) 就可以不退出程序。
4.panic 函数以错误消息处理器的方式运行; 错误消息在栈顶。不同的是,它不保证栈空间。 做任何压栈操作前,panic 函数都必须先检查是否有足够的空间 。
大多数 API 函数都有可能抛出错误, 例如在内存分配错误时就会抛出。 每个函数的文档都会注明它是否可能抛出错误。
在 C 函数内部,你可以通过调用 lu a_error 来抛出错误。
如果错误发生在保护环境之外, L ua 会先调用 panic 函数 然后调用 abort 来退出宿主程序。 你的 panic 函数只要不返回 (例如:长跳转到你在 L ua 外你自己设置的恢复点) 就可以不退出程序。
如果错误发生在保护环境之外, L ua 会先调用 panic 函数 然后调用 abort 来退出宿主程序。 你的 panic 函数只要不返回 (例如:长跳转到你在 L ua 外你自己设置的恢复点) 就可以不退出程序。
setjmp是怎么工作的
一个例子
C语言中,虽无C++或Java的异常机制,却可通过setjmp/longjmp实现类似效果。以下为简单示例。
输出结果为:
执行流程异常,似乎跨越函数,类似于goto语句,但究竟是如何实现的呢?其实质在于如何保存setjmp时的上下文环境,以及在longjmp时恢复该环境。
背景知识
理解setjmp内部机制前,需掌握执行环境概念。简单来说,执行环境包含CPU中用于记录程序执行所需信息的寄存器。以x为例,函数调用约定影响寄存器分配,如cdecl约定。
了解call指令在汇编中的实现,它将下一条指令地址压入栈,然后跳至函数入口。函数执行完毕后,从栈恢复指令地址,继续执行。
背景知识适用于x,x类似。至于其他指令集如ARM,原理大致相同。
setjmp实现
实现执行环境保存,只需如背景知识所述,将关键寄存器信息存储于jmp_buf。setjmp执行此操作,而longjmp恢复寄存器值,执行点返回setjmp调用点。
musl libc源代码示例展示setjmp实现。
setjmp完成时,jmp_buf内保存关键信息。
longjmp实现
longjmp接受两个参数,调用时栈布局如下。执行后,流程跳转至setjmp返回点,同时返回值变为传递的val。
总结
setjmp/longjmp实现执行环境保存与恢复,主要用于模拟异常处理。此外,此特性还能用于实现其他功能,后续文章将探讨更多应用。