Lua 和 C/C++ 互相調(diào)用實(shí)例分析

lua作為小巧精悍的腳本語言芜赌,易于嵌入c/c++中 作儿, 廣泛應(yīng)用于游戲AI 豆茫,實(shí)際上在任何經(jīng)常變化的邏輯上都可以使用lua實(shí)現(xiàn)迅箩,配合c/c++實(shí)現(xiàn)的底層接口服務(wù)溉愁,能夠大大降低系統(tǒng)的維護(hù)成本。下面對(duì)lua和c/c++的交互調(diào)用做一個(gè)實(shí)例分析:

lua提供了API用于在c/c++中構(gòu)造lua的運(yùn)行環(huán)境饲趋,相關(guān)接口如下:

C++

//創(chuàng)建lua運(yùn)行上下文

lua_State*

luaL_newstate(void);

//加載lua腳本文件

intluaL_loadfile(lua_State*L,const

char*filename);

lua和c/c++的數(shù)據(jù)交互通過”椆战遥”進(jìn)行

,操作數(shù)據(jù)時(shí),首先將數(shù)據(jù)拷貝到”椶人埽”上堂污,然后獲取數(shù)據(jù)龄砰,棧中的每個(gè)數(shù)據(jù)通過索引值進(jìn)行定位换棚,索引值為正時(shí)表示相對(duì)于棧底的偏移索引式镐,索引值為負(fù)時(shí)表示相對(duì)于棧頂?shù)钠扑饕饕狄?或-1為起始值娘汞,因此棧頂索引值永遠(yuǎn)為-1

,棧底索引值永遠(yuǎn)為1 辆亏。 “棧”相當(dāng)于數(shù)據(jù)在lua和c/c++之間的中轉(zhuǎn)地彻磁。每種數(shù)據(jù)都有相應(yīng)的存取接口 尘喝。

數(shù)據(jù)入”椫孟牛”接口:

C++

void(lua_pushnil)(lua_State*L);

void(lua_pushnumber)(lua_State*L,lua_Numbern);

void(lua_pushinteger)(lua_State*L,lua_Integern);

void(lua_pushlstring)(lua_State*L,constchar*s,size_tl);

void(lua_pushstring)(lua_State*L,constchar*s);

void(lua_pushboolean)(lua_State*L,intb);

void(lua_pushcclosure)(lua_State*L,lua_CFunctionfn,intn);

數(shù)據(jù)獲取接口:

C++

lua_Number(lua_tonumber)(lua_State*L,intidx);

lua_Integer(lua_tointeger)(lua_State*L,intidx);

int(lua_toboolean)(lua_State*L,intidx);

constchar*(lua_tolstring)(lua_State*L,intidx,size_t*len);

lua_CFunction(lua_tocfunction)(lua_State*L,intidx);

“椸脱撸”操作接口:

C++

int(lua_gettop)(lua_State*L);

void(lua_settop)(lua_State*L,intidx);

void(lua_pushvalue)(lua_State*L,intidx);

void(lua_remove)(lua_State*L,intidx);

void(lua_insert)(lua_State*L,intidx);

void(lua_replace)(lua_State*L,intidx);

int(lua_checkstack)(lua_State*L,intsz);

lua中定義的變量和函數(shù)存放在一個(gè)全局table中,索引值為L(zhǎng)UA_GLOBALSINDEX

呛凶,table相關(guān)操作接口:

C++

void(lua_gettable)(lua_State*L,intidx);

void(lua_getfield)(lua_State*L,intidx,constchar*k);

void(lua_settable)(lua_State*L,intidx);

void(lua_setfield)(lua_State*L,intidx,constchar*k);

當(dāng)”椖O校”中包含執(zhí)行腳本需要的所有要素(函數(shù)名和參數(shù))后殷蛇,調(diào)用lua_pcall執(zhí)行腳本:

C++

1

int(lua_pcall)(lua_State*L,intnargs,intnresults,interrfunc);

下面進(jìn)行實(shí)例說明:

func.lua

C++

#include

#include

#include

#include

//lua頭文件

#include

#include

#include

#define err_exit(num,fmt,args)??\

do{printf("[%s:%d]"fmt"\n",__FILE__,__LINE__,##args);exit(num);} while(0)

#define err_return(num,fmt,args)??\

do{printf("[%s:%d]"fmt"\n",__FILE__,__LINE__,##args);return(num);} while(0)

//lua中調(diào)用的c函數(shù)定義,實(shí)現(xiàn)加法

intcsum(lua_State*l)

{

inta=lua_tointeger(l,1);

intb=lua_tointeger(l,2);

lua_pushinteger(l,a+b);

return1;

}

intmain(intargc,char**argv)

{

lua_State*l=luaL_newstate();//創(chuàng)建lua運(yùn)行環(huán)境

if(l==NULL)err_return(-1,"luaL_newstat() failed");

intret=0;

ret=luaL_loadfile(l,"func.lua");//加載lua腳本文件

if(ret!=0)err_return(-1,"luaL_loadfile failed");

ret=lua_pcall(l,0,0,0);

if(ret!=0)err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1));

lua_getglobal(l,"width");//獲取lua中定義的變量

lua_getglobal(l,"height");

printf("height:%ld width:%ld\n",lua_tointeger(l,-1),lua_tointeger(l,-2));

lua_pop(l,1);//恢復(fù)lua的棧

inta=11;

intb=12;

lua_getglobal(l,"sum");//調(diào)用lua中的函數(shù)sum

lua_pushinteger(l,a);

lua_pushinteger(l,b);

ret=lua_pcall(l,2,1,0);

if(ret!=0)err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1));

printf("sum:%d + %d = %ld\n",a,b,lua_tointeger(l,-1));

lua_pop(l,1);

constcharstr1[]="hello";

constcharstr2[]="world";

lua_getglobal(l,"mystrcat");//調(diào)用lua中的函數(shù)mystrcat

lua_pushstring(l,str1);

lua_pushstring(l,str2);

ret=lua_pcall(l,2,1,0);

if(ret!=0)err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1));

printf("mystrcat:%s%s = %s\n",str1,str2,lua_tostring(l,-1));

lua_pop(l,1);

lua_pushcfunction(l,csum);//注冊(cè)在lua中使用的c函數(shù)

lua_setglobal(l,"csum");//綁定到lua中的名字csum

lua_getglobal(l,"mysum");//調(diào)用lua中的mysum函數(shù)准给,該函數(shù)調(diào)用本程序中定義的csum函數(shù)實(shí)現(xiàn)加法

lua_pushinteger(l,a);

lua_pushinteger(l,b);

ret=lua_pcall(l,2,1,0);

if(ret!=0)err_return(-1,"lua_pcall failed:%s",lua_tostring(l,-1));

printf("mysum:%d + %d = %ld\n",a,b,lua_tointeger(l,-1));

lua_pop(l,1);

lua_close(l);//釋放lua運(yùn)行環(huán)境

return0;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市油讯,隨后出現(xiàn)的幾起案子由捎,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件固该,死亡現(xiàn)場(chǎng)離奇詭異怔匣,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)桦沉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剿骨,“玉大人懦砂,你說我怎么就攤上這事淘菩』阍冢” “怎么了脏答?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵糕殉,是天一觀的道長(zhǎng)阿蝶。 經(jīng)常有香客問我黄绩,道長(zhǎng)羡洁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任爽丹,我火速辦了婚禮筑煮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘习劫。我一直安慰自己咆瘟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布诽里。 她就那樣靜靜地躺著,像睡著了一般飞蛹。 火紅的嫁衣襯著肌膚如雪谤狡。 梳的紋絲不亂的頭發(fā)上灸眼,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音墓懂,去河邊找鬼焰宣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛捕仔,可吹牛的內(nèi)容都是我干的匕积。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼榜跌,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼闪唆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钓葫,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤悄蕾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后础浮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帆调,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年豆同,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了番刊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡影锈,死狀恐怖撵枢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情精居,我是刑警寧澤锄禽,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站靴姿,受9級(jí)特大地震影響沃但,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜佛吓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一宵晚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧维雇,春花似錦淤刃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春铝侵,著一層夾襖步出監(jiān)牢的瞬間灼伤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工咪鲜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狐赡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓疟丙,卻偏偏與公主長(zhǎng)得像颖侄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子享郊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 第一篇 語言 第0章 序言 Lua僅讓你用少量的代碼解決關(guān)鍵問題览祖。 Lua所提供的機(jī)制是C不擅長(zhǎng)的:高級(jí)語言,動(dòng)態(tài)...
    testfor閱讀 2,680評(píng)論 1 7
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程拂蝎,因...
    小菜c閱讀 6,444評(píng)論 0 17
  • 標(biāo)簽(空格分隔): tolua++技術(shù)分析 cocos2dx+lua 前言 一直都使用 cocos2dx + lu...
    芒果有點(diǎn)甜閱讀 3,024評(píng)論 0 2
  • 當(dāng)在Lua和C之間交換數(shù)據(jù)時(shí)主要的問題是自動(dòng)回收與手動(dòng)回收內(nèi)存管理的不一致穴墅。因此,Lua 用一個(gè)抽象的棧在Lua與...
    luffier閱讀 2,664評(píng)論 0 3
  • 2017年7月23,星期天悼泌,天氣:陣雨 今天上午我們輔導(dǎo)班的家長(zhǎng)公司組織了一節(jié)課松捉,當(dāng)去聽這節(jié)課的時(shí)候必須帶著孩子去...
    于浩晨閱讀 216評(píng)論 0 6