Chinaunix首页 | 论坛 | 博客
  • 博客访问: 683635
  • 博文数量: 132
  • 博客积分: 10060
  • 博客等级: 上将
  • 技术积分: 1732
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-21 12:35
个人简介

迷惘的码农。

文章分类

全部博文(132)

文章存档

2013年(1)

2011年(2)

2010年(9)

2009年(41)

2008年(79)

我的朋友

分类:

2008-08-15 11:15:15

3 -

本节描述用于Lua的C API,即可用于宿主程序和Lua通信的C函数集合。所有API函数和相关的类型和常量在头文件中声明。

即使当我们使用术语“函数”时,API中的任何设备可能改为宏提供。所有这些宏严格地只使用它们的每个参数一次(除了第一参数,它总是个Lua状态机),因此不要产生任何隐藏的副作用(side-effects)。

同多数C库一样,Lua API函数不会检查它们的参数的可用性和一致性。可是,你可通过为文件luaconf.h中的宏使用适当的定义编译Lua来改变这种行为。

3.1 -

Lua用一个虚拟栈(virtual stack)向或从C传值。该栈中的每个元素表示一个Lua值(nil、数字、字符串,等等)。

无论何时Lua调用C,被调用函数得到一个新栈,它与以前的栈和一直活动的C函数的栈都无关。该栈最初包含传入C函数的任何参数,并且它也是C函数压入要被返回到调用者的结果的地方(见)。

为了方便的目的,API中的多数查询操作并不遵循严格的栈规范。而是通过使用index可引用栈中的任何元素:正数索引表示绝对的栈位置(从1开始);负数索引表示相对于栈顶的偏移。更明确地说,如果栈有n个元素,则索引1表示第一个元素(即第一个压入栈的元素),索引n表示最后的元素;索引-1也表示最后的元素(即栈顶的元素),索引-n表示第一个元素。如果索引处于1和栈顶之间(就是说如果1 ≤ abs(index) ≤ top)我们说它是有效的

3.2 -

当你同Lua API交互时,你有责任确保可靠性。特别地,你有责任控制栈溢出。你可用函数增长栈尺寸。

无论何时Lua调用C,它确保至少栈位置是可用的。LUA_MINSTACK被定义为20,所以通常不需要担心栈空间,除非你的代码循环将元素压栈。

多数查询函数接受的索引为可用的栈空间内的任何值,即一直到你通过设置的最大栈尺寸。 这样的索引称为认可的索引认可的索引更正式地定义如下:

     (index < 0 && abs(index) <= top) ||
(index > 0 && index <= stackspace)

注意0决不是认可的索引。

3.3 -

除非另有说明,任何接受有效索引的函数也能用伪索引调用,它们表示C代码可访问但是并不在栈中的某些Lua值。伪索引用于访问线程环境、函数环境、注册表和C函数的upvalue(见)。

线程环境(其中存在全局变量)总是在伪索引处。正运行的C函数的环境总在伪索引处。

要访问和改变全局变量的值,你可在环境表上使用常规的表操作。例如,要访问一个全局变量的值,执行

     lua_getfield(L, LUA_GLOBALSINDEX, varname);

3.4 -

当一个C函数被创建时,它可能关联了一些值,这样创建了一个C闭包;这些值称为upvalue,并且不论何时调用,它们对函数都是可访问的(见)。

只要一个C函数被调用,其upvalue就被定位在特定的伪索引处。这些伪索引由宏产生。关联到函数的第一个值在位置lua_upvalueindex(1)处,依次类推。任何访问lua_upvalueindex(n),其中n大于当前函数的upvalue的数量,产生一个可接受(但无效)的索引。

3.5 -

Lua提供一个registry,它是个预定义表,可被任何C代码用来存储它需要存储的任何Lua值。该表总是定位于伪索引处。任何C库都能存储数据到该表中,但是它应该小心地选择不同于其他库用到的键,以避免冲突。典型地,你应该在你的代码中使用含有你的库名的字符串或带有C对象地址的轻量级用户数据作为键。

注册表中的整数键被辅助库实现的引用机制使用,因此不应该用作其他目的。

3.6 -

Lua在内部使用C的longjmp设备处理错误。(如果你用C++也可选择使用一场;见文件luaconf.h。)当Lua面临任何错误时(例如内存分配错误、类型错误、语法错误和运行时错误这样的),它抛出(raise)一个错误;即执行一个长跳转。受保护的环境使用setjmp设置一个还原点;发生任何错误会跳到最近(时间上)活动的还原点。

Lua中的多数函数可能抛出错误,例如内存分配错误。每个函数的文档指出它能否抛出错误。

在C函数内可通过调用抛出错误。

阅读(1541) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~