- extern "C" {
- #include "lua.h"
- #include "lualib.h"
- #include "lauxlib.h"
- }
- ?
- #include <iostream>
- #include <string>
- using namespace std;
- ????
- int main()
- {
- ???
- ??? char *szLua_code =
- ??????? "r = string.gsub(c_Str,c_Mode,c_Tag) --宿主给的变量 "
- ??????? "u = string.upper(r)";
- ???
- ??? char *szMode = "(%w+)%s*=%s*(%w+)";
- ???
- ??? char *szStr = "key1 = value1 key2 = value2";
- ???
- ??? char *szTag = "<%1>%2</%1>";
- ?
- ??? lua_State *L = luaL_newstate();
- ??? luaL_openlibs(L);
- ?
- ???
- ??? lua_pushstring(L,szMode);
- ??? lua_setglobal(L, "c_Mode");
- ??? lua_pushstring(L,szTag);
- ??? lua_setglobal(L, "c_Tag");
- ??? lua_pushstring(L,szStr);
- ??? lua_setglobal(L, "c_Str");
- ?
- ???
- ??? bool err = luaL_loadbuffer(L,szLua_code,strlen(szLua_code),
- ??????????????? "demo") || lua_pcall(L,0);
-
??? if(err)
- ??? {
- ???????
- ??????? cerr << lua_tostring(L,-1);
- ???????
- ??????? lua_pop(L,1);
- ??? }
- ??? else
- ??? {
- ???????
- ??????? lua_getglobal(L,"r");
- ??????? cout << "r = " << lua_tostring(L,-1) << endl;
- ??????? lua_pop(L,1);
- ????????
- ??????? lua_getglobal(L,"u");
- ??????? cout << "u = " << lua_tostring(L,-1) << endl;????
- ??????? lua_pop(L,1);
- ??? }
- ??? lua_close(L);
- ??? return 0;
- }
-
-
??? 这段代码把字符串中的key=value字符串全部转换成XML格式<key>value</key> ??? 在这个例子中,C++程序通过调用lua_pushstring把C字符串压入栈顶,lua_setglobal的作用是把栈顶的数据传到Lua环境中作为全局变量。 ??? 执行代码完成后,使用lua_getglobal从Lua环境中取得全局变量压入栈顶,然后使用lua_tostring把栈顶的数据转成字符串。由于lua_tostring本身没有出栈功能,所以为了平衡(即调用前与调用后栈里的数据量不变),使用lua_pop弹出由lua_setglobal压入的数据。 ??? 从上面的例子可以看出,C++和Lua之间一直围绕着栈在转,可见栈是极为重要的。有必要列出一些Lua C API中的主要栈操作先,它们的作用直接可以从函数名中看出。 压入元素到栈里
void lua_pushnil (lua_State *L);
void lua_pushboolean (lua_State *L,int bool);
void lua_pushnumber (lua_State *L,double n);
void lua_pushlstring (lua_State *L,const char *s,size_t length);
void lua_pushstring (lua_State *L,const char *s);
void lua_pushcfunction (lua_State *L,lua_CFunction fn);
查询栈里的元素
lua_isnil (lua_State *L,int index);
lua_isboolean (lua_State *L,int index);
int lua_isnumber (lua_State *L,int index);
int lua_isstring (lua_State *L,int index);
int lua_isfunction (lua_State *L,int index);
int lua_istable (lua_State *L,int index);
int lua_isuserdata (lua_State *L,int index);
lua_islightuserdata (lua_State *L,int index);
lua_isthread (lua_State *L,int index);
转换栈里的元素
int lua_toboolean (lua_State *L,int index);
double lua_tonumber (lua_State *L,int index);
const char * lua_tostring (lua_State *L,int index);
const char * lua_tolstring (lua_State *L,int idx,size_t *len);
size_t lua_strlen (lua_State *L,int index);
lua_CFunction lua_tocfunction (lua_State *L,int idx);
void * lua_touserdata (lua_State *L,int idx);
lua_State * lua_tothread (lua_State *L,int idx);
Lua栈的维护
int lua_gettop (lua_State *L);
取得栈顶元素的索引,即栈中元素的个数
void lua_settop (lua_State *L,int index);
设置栈顶索引,即设置栈中元素的个数,如果index<0,则从栈顶往下数,下同
void lua_pushvalue (lua_State *L,int index);
把栈中指定索引的元素复制一份到栈顶
void lua_remove (lua_State *L,int index);
删除指定索引的元素
void lua_insert (lua_State *L,int index);
移动栈顶元素到指定索引的位置,栈中数目没有改变
void lua_replace (lua_State *L,int index);
从栈顶弹出元素值并将其设置到指定索引位置,栈中的数目减一
int lua_checkstack (lua_State *L,int extra);
确保堆栈上至少有 extra 个空位。如果不能把堆栈扩展到相应的尺寸,函数返回 false 。这个函数永远不会缩小堆栈。
int lua_pop(L,n)
从栈顶弹出n个元素,它是一个lua_settop的包装:#define lua_pop(L,n) lua_settop(L,-(n)-1)
表的操作 上面的列表中并没有lua_pushtable和lua_totable,那么怎样取得或设置Lua中的table数据呢? 在Lua中,table是一个很重要的数据类型,在table中不仅可以象C中的数据一样放一组数据,还可以象map一样以key=value的方式存放数据,如Lua代码中的:
tb = {"abc",12,true,x=10,y=20,z=30}
??? 前三个数据可以用tb[1]~tb[3]取得 ??? 而后三个数据通过tb.x,tb.y,tb.z取得 尽管看起来很牛叉,不过剥开神奇的外衣,实际上Lua的table中,所有的数据都是以key=value的形式存放的,这句Lua代码也可以写成:
tb = {[1]="abc",[2]=12,[3] = true,["x"]=10,["y"]=20,["z"]=30}
??? 它的形式就是[key]=value,所谓的tb.x只是tb["x"]的语法糖而已,如果愿意,也可以用tb["x"]取得这个数据10。 我们把上面的例子改成使用表的
- ...
-
int main()
- {
- ???
- ??? char *szLua_code =
- ??????? "x = {} --用于存放结果的table "
- ??????? "x[1],x[2] = string.gsub(c.Str,c.Mode,c.Tag) --x[1]里是结果,x[2]里是替换次数 "
- ??????? "x.u = string.upper(x[1])";
- ???
- ??? char *szMode = "(%w+)%s*=%s*(%w+)";
- ???
- ??? char *szStr = "key1 = value1 key2 = value2";
- ???
- ??? char *szTag = "<%1>%2</%1>";
- ?
- ??? lua_State *L = luaL_newstate();
- ??? luaL_openlibs(L);
- ?
- ???
- ??? lua_newtable(L);???
- ??? lua_pushstring(L,"Mode");
- ??? lua_pushstring(L,szMode);
- ???
- ???
- ??? lua_settable(L,-3);
- ???
- ?
- ??? lua_pushstring(L,"Tag");
- ??? lua_pushstring(L,szTag);
- ??? lua_settable(L,-3);???
- ?
- ??? lua_pushstring(L,"Str");
- ??? lua_pushstring(L,szStr);
- ??? lua_settable(L,-3);???
- ?
- ??? lua_setglobal(L,"c");
- ?
- ???
- ??? bool err = luaL_loadbuffer(L,
- ??????????????? "demo") || lua_pcall(L,0);
- ??? if(err)
- ??? {
- ???????
- ??????? cerr << lua_tostring(L,-1);
- ???????
- ??????? lua_pop(L,1);
- ??? }
- ??? else
- ??? {
- ???????
- ??????? lua_getglobal(L,"x");
- ?
- ???????
- ??????? if(lua_istable(L,-1))
- ??????? {
- ???????????
- ??????????? lua_pushstring(L,"u");???
- ???????????
- ??????????? lua_gettable(L,-2);
- ???????????
- ???????????
- ??????????? cout << "x.u = " << lua_tostring(L,-1) << endl;
- ??????????? lua_pop(L,1);
- ????????????
- ???????????
- ??????????? for(int i=1; i<=2; i++)
- ??????????? {
- ???????????????
- ??????????????? lua_pushnumber(L,i);
- ??????????????? lua_gettable(L,-2);
- ??????????????? cout << "x[" << i <<"] = " << lua_tostring(L,-1) << endl;
- ??????????????? lua_pop(L,1);
- ??????????? }
- ??????? }
- ?
- ???????
- ??????? lua_pop(L,1);
- ??? }
- ??? lua_close(L);
- ??? return 0;
- }
本例中用到的新Lua C API是:
void lua_newtable (lua_State *L);
新建一个空的table并压入栈顶。
void lua_settable (lua_State *L,int idx);
lua_settable以table在栈中的索引作为参数,并将栈顶的key和value出栈,用这两个值修改table。
void lua_gettable (lua_State *L,int idx);
lua_gettable以table在栈中的索引作为参数,弹出栈顶的元素作为key,返回与key对应的value并压入栈顶。
最后,Lua告别针对table提供了存取函数
void lua_rawgeti (lua_State *L,int n)
取得table[n]并放到栈顶,上例中69-70行的lua_pushnumber(L,i);lua_gettable(L,-2);可以用lua_rawgeti(L,-1)代替。
lua_getfield (lua_State *L,const char *k)
取得table.k并放到栈顶,上例中57-59行的lua_pushstring(L,"u");lua_gettable(L,-2);可以替换成lua_getfield(L,-1,"u")。
void lua_setfield (lua_State *L,const char *k)
把栈顶的数据作为value放入table.k中,上例中的形如lua_pushstring(L,"key");lua_pushstring(L,value);lua_settable(L,-3);可以改成lua_pushstring(L,value);lua_setfield(L,-2,"key");的形式。
void lua_rawseti (lua_State *L,int n)
把栈顶的数据作为value放入table[n]中
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|