因为受到经济危机的影响,我在 bokee.com 的博客可能随时出现无法访问的情况;因此将2005年到2006年间在 bokee.com 撰写的博客文章全部迁移到 csdn 博客中来,本文正是其中一篇迁移的文章。
把堆栈中的值转换为指定的C类型,有如下函数可用:
int lua_toboolean (lua_State *L, int index);<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
lua_Number lua_tonumber (lua_State *L, int index);
const char *lua_tostring (lua_State *L, int index);
size_t lua_strlen (lua_State *L, int index);
lua_CFunction lua_tocfunction (lua_State *L, int index);
void *lua_touserdata (lua_State *L, int index);
lua_State *lua_tothread (lua_State *L, int index);
void *lua_topointer (lua_State *L, int index);
这些函数可通过任意可接受索引调用,如果用无效索引为参数,则和给定值并不匹配类型一样。
lua_toboolean转换指定索引lua值为C“布尔型”值(0或1)。当lua值仅为false或nil时返回0(如果你仅想接受一个真正的布尔值,可以先使用lua_isboolean去测试这个值的类型。
lua_tonumber转换指定索引的值为数字(lua_Number默认为double)。这一lua值必须数字或可转换为数字的字符串(参考<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><span lang="EN-US">2.2.1</span></chsdate>),否则lua_tonumber返回0。
lua_tostring将指定索引的值转换为字符串(const char*)。lua值必须为字符串或数字,否则返回NULL。当值为数字,lua_tostring将会把堆栈的原值转换为字符串(当lua_tostring应用到键值上时会使lua_next出现难以找出原因的错误)。lua_tostring返回一个完全对齐的字符串指针,这一字符串总是’\<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="’">0<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><span lang="EN-US">’</span></span></chmetcnv>结尾(和C一样),但可能含有其它的0。如果你不知道一个字符串有多少个0,你可以使用lua_strlen取得真实长度。因为lua有垃圾收集机制,因此不保证返回的字符串指针在对应的值从堆栈中删除后仍然有效。如果你以后还要用到当前函数返回的字符串,你应当备份它或者将它放到registry中(参考3.18)。
lua_tofunction将堆栈中的值转换为C函数指针,这个值必须为C函数指针,否则返回NULL。数据类型lua_CFunction将在3.16节讲述。
lua_tothread转换堆栈中的值为lua线程(以lua_State*为表现形式),此值必须是一个线程,否则返回NULL。
lua_topointer转换堆栈中的值为通用C指针(void*)。这个值必须为userdata、表、线程或函数,否则返回NULL。lua保证同一类型的不同对象返回不同指针。没有直接方法将指针转换为原值,这一函数通常用以获取调试信息。
lua_touserdata在3.8节讲述。
下列API能将C值压入堆栈
void lua_pushboolean (lua_State *L, int b);
void lua_pushnumber (lua_State *L, lua_Number n);
void lua_pushlstring (lua_State *L, const char *s, size_t len);
void lua_pushstring (lua_State *L, const char *s);
void lua_pushnil (lua_State *L);
void lua_pushcfunction (lua_State *L, lua_CFunction f);
void lua_pushlightuserdata (lua_State *L, void *p);
这些函数接受一个C值,并将其转换为对应的lua值,然后将其压入堆栈。lua_pushlstring和lua_pushstring对给定的字符串生成一个可以互转的拷贝,这是个例外。lua_pushstring能压C字符串(即以0结尾并且内部没有0),否则建议使用更通用的lua_pushlstring,它能指定长度。
你同样可以压入“格式化”字符串:
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp);
这两个函数向堆栈压入格式化字符串并返回指向字符串的指针。它们跟sprintf和vsprintf很象但有如下的重要不同:
·你不用申请内存去保存格式化结果,这结果是一个lua字符串并且lua自己会小心管理内存(并通过垃圾收集机制释放)。
·使用转义字符受限。它们没有标志量、宽度和精确度。转义字符能够是’%%’(插入一个”%”)、’%s’(插入一个以0结尾的字符串)、’%f’(插入一个lua_Number)、’%d’(插入一个int)和’%c’(插入一个用int表示的字符)。
函数
void lua_concat (lua_State *L, int n);
用以联结堆栈上部的n个元素,并将它们出栈,将结果放在栈顶。如果n为1,结果为原来的字符串(因为函数什么也没有做);如果n为0,则结果为一个空字符串。联结这一术语依从lua的语义(参考<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><span lang="EN-US">2.5.4</span></chsdate>)。