lua和c的交互

lua和c的交互,第1张

概述extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" }   #include <iostream> #include <string> using namespace std;      int main() {     //Lua示例代码     char *szLua_code =         "r  extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" }   #include <iostream> #include <string> using namespace std;      int main() {     //Lua示例代码     char *szLua_code =         "r = string.gsub(c_Str, c_Mode, c_Tag) --宿主给的变量 "         "u = string.upper(r)"; //Lua的字符串模式 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     lua_pushstring(L, szMode);     lua_setglobal(L, "c_Mode"); "c_Tag"); "c_Str"); //执行 bool err = luaL_loadbuffer(L, szLua_code, strlen(szLua_code),                 "demo") || lua_pcall(L, 0, 0);     if(err)     {         //如果错误,显示         cerr << lua_tostring(L, -1); //d出栈顶的这个错误信息         lua_pop(L, 1);     }     else     {         //Lua执行后取得全局变量的值         lua_getglobal(L, "r");         cout << "r = " << lua_tostring(L,-1) << endl;         lua_pop(L, 1);          "u");         cout << "u = " << lua_tostring(L,-1) << endl;         }     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_popd出由lua_setglobal压入的数据。
    从上面的例子可以看出,C++和Lua之间一直围绕着栈在转,可见栈是极为重要的。有必要列出一些Lua C API中的主要栈 *** 作先,它们的作用直接可以从函数名中看出。
压入元素到栈里

@H_756_301@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);


查询栈里的元素

@H_756_301@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);

 

转换栈里的元素

@H_756_301@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栈的维护

@H_756_301@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); 从栈顶d出元素值并将其设置到指定索引位置,栈中的数目减一int lua_checkstack (lua_State *L,int extra); 确保堆栈上至少有 extra 个空位。如果不能把堆栈扩展到相应的尺寸,函数返回 false 。这个函数永远不会缩小堆栈。int lua_pop(L,n) 从栈顶d出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]="

    它的形式就是[key]=value,所谓的tb.x只是tb["x"]的语法糖而已,如果愿意,也可以用tb["x"]取得这个数据10。
我们把上面的例子改成使用表的

... int main() {     //Lua示例代码,使用table     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])";     //Lua的字符串模式     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);   //把一个tabele送给Lua     lua_newtable(L);    //新建一个table并压入栈顶     lua_pushstring(L, "Mode");// key     lua_pushstring(L, szMode);// value //设置newtable[Mode]=szMode //由于上面两次压栈,现在table元素排在栈顶往下数第三的位置     lua_settable(L, -3); //lua_settable会自己d出上面压入的key和value "Tag");// key // value     lua_settable(L, -3);    //设置newtable[Tag]=szTag "Str");//设置newtable[Str]=szStr     lua_setglobal(L,"c"); //将栈顶元素(newtable)置为Lua中的全局变量c //执行                 "demo") || lua_pcall(L, 0);     if(err)     {         //如果错误,显示         cerr << lua_tostring(L, -1); //d出栈顶的这个错误信息         lua_pop(L, 1);     }     else     {         //Lua执行后取得全局变量的值         lua_getglobal(L, "x"); //这个x应该是个table         if(lua_istable(L,-1))         {             //取得x.u,即x["u"]             lua_pushstring(L,"u");    //key //由于这次压栈,x处于栈顶第二位置             lua_gettable(L,-2); //lua_gettable会d出上面压入的key,然后把对应的value压入             //取得数据,然后从栈中d出这个value             cout << "x.u = " << lua_tostring(L,-1) << endl;             lua_pop(L, 1);              //取得x[1]和x[2]             for(int i=1; i<=2; i++)             {                 //除了key是数字外,与上面的没什么区别                 lua_pushnumber(L,i);                 lua_gettable(L,-2);                 cout << "x[" << i <<"] = " << lua_tostring(L,-1) << endl;                 lua_pop(L,108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">             }         } //d出栈顶的x         lua_pop(L,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">     }     lua_close(L); return 0; }

本例中用到的新Lua C API是:

@H_756_301@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在栈中的索引作为参数,d出栈顶的元素作为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]中 @H_756_301@转自:http://blog.csdn.net/zhangjingyangguang/article/details/5221691 总结

以上是内存溢出为你收集整理的lua和c的交互全部内容,希望文章能够帮你解决lua和c的交互所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1246464.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存