Lua C API的正确用法

本文探讨了在C++工程中使用Lua库时的异常处理机制。详细解释了使用不同编译器对Lua库编译时异常处理的区别,并介绍了如何在C++中正确处理Lua C API抛出的异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.codingnow.com/2015/05/lua_c_api.html

http://blog.youkuaiyun.com/oilcode/article/details/51086147

https://www.lua.org/manual/5.3/

https://cloudwu.github.io/lua53doc/manual.html

 

关于异常处理

1. 如果要在C++工程中使用Lua库,需要用C++的编译器来编译Lua库,这会促使编译后的Lua库使用try...catch的方式来捕获异常。随后,当通过Lua调用C++函数的时候,如果该C++函数抛出了一个异常,Lua虚拟机就会正常的捕获这个异常。如果一个使用C语言编译器编译的Lua库被使用到了一个C++工程中,该Lua库会使用setjmp/longjmp的机制来处理异常,那么C++抛出的异常就不会被Lua虚拟机捕获。

2. 不能在C++中用try...catch来捕获Lua C API抛出的异常,因为Lua虚拟机需要通过捕获这个异常来进行异常处理,如果C++捕获了该异常将破坏Lua虚拟机后续的执行。C++应该使用lua_pcalll来处理异常。

3. 如果C++中调用的一个Lua C API抛出了异常,那么该异常语句之后的所有调用都不会执行。

 

Lua 5.3 Reference Manual

4.8 – Functions and Types

Here we list all functions and types from the C API in alphabetical order. Each function has an indicator like this: [-o, +p, x]

The first field, o, is how many elements the function pops from the stack. The second field, p, is how many elements the function pushes onto the stack. (Any function always pushes its results after popping its arguments.) A field in the form x|y means the function can push (or pop) x or y elements, depending on the situation; an interrogation mark '?' means that we cannot know how many elements the function pops/pushes by looking only at its arguments (e.g., they may depend on what is on the stack). The third field, x, tells whether the function may raise errors: '-' means the function never raises any error; 'm' means the function may raise out-of-memory errors and errors running a __gc metamethod; 'e' means the function may raise any errors (it can run arbitrary Lua code, either directly or through metamethods); 'v' means the function may raise an error on purpose.

 

lua_pcall

1. 不会抛出异常

2. 总是会从栈顶删除函数及参数

 

luaL_openlibs的实现 

LUALIB_API void luaL_openlibs (lua_State *L) {
  const luaL_Reg *lib;
  /* "require" functions from 'loadedlibs' and set results to global table */
  for (lib = loadedlibs; lib->func; lib++) {
    luaL_requiref(L, lib->name, lib->func, 1);
    lua_pop(L, 1); /* remove lib */
  }
}

 

对象的成员变量靠构造函数定义,这样所有的成员变量都在对象中

方法在 metatable中

继承体系靠为__index赋值一个table实现

 

点号和冒号的区别

点号相当于在表里找一个键对应的值。冒号应用在成员函数调用,也就是相当于先找到键对应的值,这个Value应该是一个function类型的值,然后在调用该函数的时候,将冒号前面的表当做第一个参数传入函数。

元方法不适用冒号的调用方法。元方法会自动将表作为第一个参数传入。

 

注册表

注册表是一个Lua预定义在伪索引LUA_REGISTRYINDEX处的一个表。这个表用来存储C代码中需要存储的值。只有C能访问能访问这个表。这个表中所使用的键和普通的表略有不同。通常用户需要使用字符串来作为键(通常用作metatable的名字;以下划线开头的名字是Lua保留的),而整数键被用来实现引用机制(luaL_ref)不能移作他用。

LUA_RIDX_GLOBALS
LUA_RIDX_MAINTHREAD

是两个注册表中预定义的特殊索引。

转载于:https://www.cnblogs.com/lilei9110/p/6770255.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值