[轉(zhuǎn)]lua與c的詳細(xì)堆棧說明

當(dāng)在Lua和C之間交換數(shù)據(jù)時(shí)主要的問題是自動(dòng)回收與手動(dòng)回收內(nèi)存管理的不一致筐喳。因此彭雾,Lua 用一個(gè)抽象的棧在Lua與C之間交換值疚顷。
本文目錄:

1壮池、c與lua的取值傳值
(1)取值(到c)
(2)傳值(到lua)

2硅瞧、堆棧操作api
(1) 壓入元素
(2) 查詢?cè)兀?) 其他堆棧操作3份乒、堆棧操作實(shí)例
(1)一些堆棧操作和打印堆棧上所有變量的例子
(2)提供一個(gè)打印一張lua表的c的api函數(shù)4、項(xiàng)目例子

本文內(nèi)容:
1腕唧、c與lua的取值傳值
(1)取值
棧中的每一條記錄都可以保存任何Lua值或辖。無論你何時(shí)想要從Lua請(qǐng)求一個(gè)值(比如一個(gè)全局變量的值),調(diào)用Lua枣接,被請(qǐng)求的值將會(huì)被壓入棧颂暇。
Lua以一個(gè)嚴(yán)格的LIFO規(guī)則(后進(jìn)先出;也就是說但惶,始終存取棧頂)來操作棧耳鸯。當(dāng)你調(diào)用Lua時(shí),它只會(huì)改變棧頂部分膀曾。你的C代碼卻有更多的自由县爬;更明確的來講,你可以查詢棧上的任何元素添谊,甚至是在任何一個(gè)位置插入和刪除元素财喳。
(2)傳值
無論你何時(shí)想要傳遞一個(gè)值給Lua,首先將這個(gè)值壓入棧,然后調(diào)用Lua(這個(gè)值將被彈出)耳高。我們?nèi)匀恍枰粋€(gè)不同的函數(shù)將每種C類型壓入棧和一個(gè)不同函數(shù)從棧上取值(只是取出不是彈出)扎瓶。
因?yàn)闂J怯蒐ua來管理的,垃圾回收器知道那個(gè)值正在被C使用泌枪。幾乎所有的API函數(shù)都用到了棧栗弟。例如,luaL_loadbuffer把它的結(jié)果留在了棧上(被編譯的chunk或一條錯(cuò)誤信息);lua_pcall從棧上獲取要被調(diào)用的函數(shù)并把任何臨時(shí)的錯(cuò)誤信息放在這里工闺。
2乍赫、堆棧操作api
(1) 壓入元素API有一系列壓棧的函數(shù),它將每種可以用C來描述的Lua類型壓棧:空值(nil)用lua_pushnil陆蟆,數(shù)值型(double)用lua_pushnumber雷厂,布爾型(在C中用整數(shù)表示)用lua_pushboolean,任意的字符串(char*類型叠殷,允許包含”字符)用lua_pushlstring改鲫,C語言風(fēng)格(以”結(jié)束)的字符串(const char*)用lua_pushstring: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);同樣也有將C函數(shù)和userdata值壓入棧的函數(shù),稍后會(huì)討論到它們林束。Lua中的字符串不是以零為結(jié)束符的像棘;它們依賴于一個(gè)明確的長(zhǎng)度,因此可以包含任意的二進(jìn)制數(shù)據(jù)壶冒。將字符串壓入串的正式函數(shù)是lua_pushlstring缕题,它要求一個(gè)明確的長(zhǎng)度作為參數(shù)。對(duì)于以零結(jié)束的字符串胖腾,你可以用lua_pushstring(它用strlen來計(jì)算字符串長(zhǎng)度)烟零。Lua從來不保持一個(gè)指向外部字符串(或任何其它對(duì)象,除了C函數(shù)——它總是靜態(tài)指針)的指針咸作。對(duì)于它保持的所有字符串锨阿,Lua要么做一份內(nèi)部的拷貝要么重新利用已經(jīng)存在的字符串。因此记罚,一旦這些函數(shù)返回之后你可以自由的修改或是釋放你的緩沖區(qū)墅诡。無論你何時(shí)壓入一個(gè)元素到棧上,你有責(zé)任確保在棧上有空間來做這件事情桐智。記住末早,你現(xiàn)在是C程序員;Lua不會(huì)寵著你酵使。當(dāng)Lua在起始以及在Lua調(diào)用C的時(shí)候荐吉,棧上至少有20個(gè)空閑的記錄(lua.h中的LUA_MINSTACK宏定義了這個(gè)常量)焙糟。對(duì)于多數(shù)普通的用法棧是足夠的穿撮,所以通常我們不必去考慮它痪欲。無論如何,有些任務(wù)或許需要更多的椧堤撸空間(如礁扮,調(diào)用一個(gè)不定參數(shù)數(shù)目的函數(shù))知举。在這種情況下太伊,或許你需要調(diào)用下面這個(gè)函數(shù):int lua_checkstack (lua_State *L, int sz);它檢測(cè)棧上是否有足夠你需要的空間(稍后會(huì)有關(guān)于它更多的信息)僚焦。
(2) 查詢?cè)谹PI用索引來訪問棧中的元素芳悲。在棧中的第一個(gè)元素(也就是第一個(gè)被壓入棧的)有索引1,下一個(gè)有索引2,以此類推踢故。我們也可以用棧頂作為參照來存取元素惹苗,利用負(fù)索引。在這種情況下桩蓉,-1指出棧頂元素(也就是最后被壓入的)院究,-2指出它的前一個(gè)元素,以此類推伙窃。例如样漆,調(diào)用lua_tostring(L, -1)以字符串的形式返回棧頂?shù)闹怠N覀兿旅鎸⒖吹剑谀承﹫?chǎng)合使用正索引訪問棧比較方便呻右,另外一些情況下鞋喇,使用負(fù)索引訪問棧更方便。API提供了一套lua_is*函數(shù)來檢查一個(gè)元素是否是一個(gè)指定的類型落塑,*可以是任何Lua類型罐韩。因此有l(wèi)ua_isnumber,lua_isstring,lua_istable以及類似的函數(shù)伴逸。所有這些函數(shù)都有同樣的原型:int lua_is… (lua_State *L, int index);lua_isnumber和lua_isstring函數(shù)不檢查這個(gè)值是否是指定的類型,而是看它是否能被轉(zhuǎn)換成指定的那種類型错蝴。例如顷锰,任何數(shù)字類型都滿足lua_isstring。還有一個(gè)lua_type函數(shù)肛宋,它返回棧中元素的類型束世。(lua_is*中的有些函數(shù)實(shí)際上是用了這個(gè)函數(shù)定義的宏)在lua.h頭文件中,每種類型都被定義為一個(gè)常量:LUA_TNIL沉帮、LUA_TBOOLEAN贫堰、LUA_TNUMBER、LUA_TSTRING喇勋、LUA_TTABLE偎行、LUA_TFUNCTION贰拿、LUA_TUSERDATA以及LUA_TTHREAD。這個(gè)函數(shù)主要被用在與一個(gè)switch語句聯(lián)合使用汗盘。當(dāng)我們需要真正的檢查字符串和數(shù)字類型時(shí)它也是有用的為了從棧中獲得值,這里有l(wèi)ua_to*函數(shù):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);size_t lua_strlen (lua_State *L, int index);即使給定的元素的類型不正確癌椿,調(diào)用上面這些函數(shù)也沒有什么問題菱阵。在這種情況下,lua_toboolean都办、lua_tonumber和lua_strlen返回0虑稼,其他函數(shù)返回NULL。由于ANSI C沒有提供有效的可以用來判斷錯(cuò)誤發(fā)生數(shù)字值歌懒,所以返回的0是沒有什么用處的溯壶。對(duì)于其他函數(shù)而言且改,我們一般不需要使用對(duì)應(yīng)的lua_is*函數(shù):我們只需要調(diào)用lua_is*,測(cè)試返回結(jié)果是否為NULL即可又跛。Lua_tostring函數(shù)返回一個(gè)指向字符串的內(nèi)部拷貝的指針效扫。你不能修改它(使你想起那里有一個(gè)const)。只要這個(gè)指針對(duì)應(yīng)的值還在棧內(nèi)浩习,Lua會(huì)保證這個(gè)指針一直有效济丘。當(dāng)一個(gè)C函數(shù)返回后洽蛀,Lua會(huì)清理他的棧疟赊,所以近哟,有一個(gè)原則:永遠(yuǎn)不要將指向Lua字符串的指針保存到訪問他們的外部函數(shù)中(就算Lua_to* 和lua_is*沒有彈棧操作,也不該使用c指針指向lua字符串的地址)疯淫。
Lua_string返回的字符串結(jié)尾總會(huì)有一個(gè)字符結(jié)束標(biāo)志0戳玫,但是字符串中間也可能包含0,lua_strlen返回字符串的實(shí)際長(zhǎng)度币绩。特殊情況下府阀,假定棧頂?shù)闹凳且粋€(gè)字符串肌似,下面的斷言(assert)總是有效的:const char *s = lua_tostring(L, -1);size_t l = lua_strlen(L, -1);assert(s[l] == ”);assert(strlen(s) <= l);
(3) 其他堆棧操作除開上面所提及的C與堆棧交換值的函數(shù)外,API也提供了下列函數(shù)來完成通常的堆棧維護(hù)工作:(3-1)int lua_gettop (lua_State *L);
函數(shù)lua_gettop返回堆棧中的元素個(gè)數(shù)力细,它也是棧頂元素的索引固额。注意一個(gè)負(fù)數(shù)索引-x對(duì)應(yīng)于正數(shù)索引gettop-x+1。(3-2)void lua_settop (lua_State *L, int index);
lua_settop設(shè)置棧頂(也就是堆棧中的元素個(gè)數(shù))為一個(gè)指定的值逝慧。如果開始的棧頂高于新的棧頂啄糙,頂部的值被丟棄隧饼。否則,為了得到指定的大小這個(gè)函數(shù)壓入相應(yīng)個(gè)數(shù)的空值(nil)到棧上燕雁。特別的,lua_settop(L,0)清空堆棧僧免。你也可以用負(fù)數(shù)索引作為調(diào)用lua_settop的參數(shù)懂衩;那將會(huì)設(shè)置棧頂?shù)街付ǖ乃饕@眠@種技巧谒所,API提供了下面這個(gè)宏沛申,它從堆棧中彈出n個(gè)元素:#define lua_pop(L,n) lua_settop(L, -(n)-1)(3-3)void lua_pushvalue (lua_State *L, int index);
函數(shù)lua_pushvalue壓入堆棧上指定索引的一個(gè)摶貝到棧頂姐军;(3-4)void lua_remove (lua_State *L, int index);
lua_remove移除指定索引位置的元素奕锌,并將其上面所有的元素下移來填補(bǔ)這個(gè)位置的空白;(3-5)void lua_insert (lua_State *L, int index);
lua_insert移動(dòng)棧頂元素到指定索引的位置饼丘,并將這個(gè)索引位置上面的元素全部上移至棧頂被移動(dòng)留下的空隔辽话;(3-6)void lua_replace (lua_State *L, int index);最后,lua_replace從棧頂彈出元素值并將其設(shè)置到指定索引位置典徘,沒有任何移動(dòng)操作益咬。
(3-7)注意到下面的操作對(duì)堆棧沒有任何影響:lua_settop(L, -1);lua_insert(L, -1);
3幽告、堆棧操作實(shí)例(1)一些堆棧操作和打印堆棧上所有變量的例子

//打印棧上的所有的變量  
static void stackDump (lua_State *L)  
{  
    int i;  
    int top = lua_gettop(L);  
    for (i = 1; i <= top; i++)  
    {  
        int t = lua_type(L, i);  
        switch (t)  
        {  
            case LUA_TSTRING:  
                printf("%s", lua_tostring(L, i));  
            break;  
            case LUA_TBOOLEAN:  
                printf(lua_toboolean(L, i)? "true":"false");  
            break;  
            case LUA_TNUMBER:  
                printf("%g", lua_tonumber(L, i));  
                break;  
            default:  
                printf("%s", lua_typename(L, t));  
            break;  
        }  
        printf(" ");  
    }  
    printf("\n");  
}  
  
  
int main (void)   
{  
    lua_State *L = lua_open();  
    //1 依次壓入幾個(gè)變量 true冗锁,10,nil蒿讥,"hello"   
    printf("1:\n");  
    lua_pushboolean(L, 1);  
    lua_pushnumber(L, 10);  
    lua_pushnil(L);  
    lua_pushstring(L,"hello");  
    stackDump(L);//true 10 nil hello   
    //2  
    printf("2:\n");  
    lua_pushvalue(L, -4);  
    stackDump(L);//true 10 nil hello true   
    //3  用棧頂更換第三個(gè)  
    printf("3:\n");  
    lua_replace(L, 3);  
    stackDump(L);//true 10 true hello   
    //4 設(shè)置棧變量為6個(gè)  
    printf("4:\n");  
    lua_settop(L, 6);  
    stackDump(L);//true 10 true hello nil nil   
    //5 移除從棧頂往下數(shù)的第三個(gè)  
    printf("5:\n");  
    lua_remove(L, -3);  
    stackDump(L);//true 10 true nil nil   
    //6 設(shè)置-5位置的變量作為棧頂變量  
    printf("6:\n");  
    lua_settop(L, -5);  
    stackDump(L);//true  
    //7  
    lua_close(L);  
    return 0;  
}  

輸出結(jié)果(輸出是從棧底到棧頂):
1:
true 10 nil hello
2:
true 10 nil hello true
3:
true 10 true hello
4:
true 10 true hello nil nil
5:
true 10 true nil nil
6:
true
(2)提供一個(gè)打印一張表的c的api函數(shù)

void tableDump (lua_State *L,int index)  
{  
        if (!lua_istable(L,index))  
        {  
                return;  
        }  
        int tLen = lua_objlen(L,index);  
  
        for(int i = 0;i < tLen;i++)  
        {  
                lua_rawgeti(L,index,i+1);  
                int t = lua_type(L, -1);  
                switch (t) {  
                        case LUA_TSTRING:  
                                printf("t[%d]=%s ",i+1, lua_tostring(L,-1));  
                                break;  
                        case LUA_TBOOLEAN:  
                                printf("t[%d]=%s ",i+1,lua_toboolean(L, -1)? "true":"false");  
                                break;  
                        case LUA_TNUMBER:  
                                printf("t[%d]=%g ",i+1, lua_tonumber(L, -1));  
                                break;  
                        default:  
                        printf("t[%d]=%s ",i+1, lua_typename(L, t));  
                        break;  
                }  
                lua_pop(L,1);  
        }  
        printf("\n");  
}  

4媒殉、項(xiàng)目例子
這里是將一個(gè)c++的配置壓入到lua一張叫QuestData(任務(wù)表)的全局的表里。這個(gè)例子可以看出c構(gòu)建lua表數(shù)據(jù)的基本應(yīng)用

void QuestAccessor::makeScriptQuestData()  
{  
  QuestConfig** ppQuestList = m_Quest.own_ptr();  
  INT_PTR nCount = m_Quest.length();  
  lua_State* L = g_Script->getLuaState();  
  lua_newtable(L);//QuestData表  
  for (INT_PTR i = 1; i < nCount; ++i)  
  {  
    pushToQuestData(L, ppQuestList[i]);  
  }  
  lua_setglobal(L, "QuestData");//設(shè)置該表作為全局的表全封,名為QuestData  
}  
 /* 
QuestData[questId] = {  
        name = "任務(wù)名", 
        acceptTalk = { "111", "222", "333" },  
        acceptReply = {"11", "22", "33"}, 
        completeTalk = { "aaa", "bbb", "ccc" }, 
        completeReply = {"aa", "bb", "cc"}, 
} 
*/  
void QuestAccessor::pushToQuestData(lua_State* L, QuestConfig *quest)//最外面建了一張表quests  
{  
    lua_newtable(L);//新建questId作為QuestData表的下標(biāo)的表  
    lua_pushvalue(L,-1);//拷貝表引用到棧頂  
    lua_rawseti(L, -3, quest->nQid);//設(shè)置questId作為QuestData表的下標(biāo)的表  
    //name = "quest-name"  
    lua_pushstring(L, quest->sName);  
    lua_setfield(L, -2, "name");//questId 表的名字  
    const QuestAccessor::TalkStruct* pTalkStruct =  &(m_questTalkList.get(quest->nQid));  
    if (NULL != pTalkStruct)  
    {  
    if (pTalkStruct->accept.nCount > 0)  
    {  
            lua_newtable(L);//acceptTalk 表  
            lua_pushvalue(L,-1);  
            lua_setfield(L, -3, "acceptTalk");  
      for (int i = 0; i < pTalkStruct->accept.nCount; ++i)  
      {  
        lua_pushstring(L, pTalkStruct->accept.talkList[i].c_str());  
        lua_rawseti(L, -2, i + 1);  
      }  
      lua_pop(L, 1);//彈出acceptTalk表  
      lua_newtable(L);//新建acceptReply表  
      lua_pushvalue(L, -1);  
      lua_setfield(L, -3, "acceptReply");//設(shè)置acceptReply表到questId表  
      for (int i = 0; i < pTalkStruct->accept.nCount; ++i)  
      {  
        lua_pushstring(L, pTalkStruct->accept.replyList[i].c_str());  
        lua_rawseti(L, -2, i+1);  
      }  
      lua_pop(L, 1);//彈出acceptReply標(biāo)  
    }  
        if (pTalkStruct->complete.nCount > 0)  
    {  
      lua_newtable(L);//新建completeTalk表  
      lua_pushvalue(L, -1);  
      lua_setfield(L, -3, "completeTalk");  
      for (int i = 0; i < pTalkStruct->complete.nCount; ++i)  
      {  
        lua_pushstring(L, pTalkStruct->complete.talkList[i].c_str());  
        lua_rawseti(L, -2, i + 1);  
      }  
      lua_pop(L, 1);  
  
  
      lua_newtable(L);//新建completeReply表  
      lua_pushvalue(L, -1);  
      lua_setfield(L, -3, "completeReply");  
      for (int i = 0; i < pTalkStruct->complete.nCount; ++i)  
      {  
        lua_pushstring(L, pTalkStruct->complete.replyList[i].c_str());  
        lua_rawseti(L, -2, i+1);  
      }  
      lua_pop(L, 1);  
    }  
  }  
  lua_pop(L, 1);//彈出questId表  
}  

轉(zhuǎn)自:http://blog.csdn.net/chenjiayi_yun/article/details/23772627

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末攒暇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子就轧,更是在濱河造成了極大的恐慌田度,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乎莉,死亡現(xiàn)場(chǎng)離奇詭異奸笤,居然都是意外死亡揭保,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門存筏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來味榛,“玉大人搏色,你說我怎么就攤上這事∑到危” “怎么了烁焙?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵骄蝇,是天一觀的道長(zhǎng)操骡。 經(jīng)常有香客問我册招,道長(zhǎng),這世上最難降的妖魔是什么是掰? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任冀惭,我火速辦了婚禮掀鹅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘戚丸。我一直安慰自己扔嵌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著独旷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪案疲。 梳的紋絲不亂的頭發(fā)上麻养,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天鳖昌,我揣著相機(jī)與錄音低飒,去河邊找鬼懂盐。 笑死允粤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的类垫。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼售躁!你這毒婦竟也來了陪捷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤啡直,失蹤者是張志新(化名)和其女友劉穎苍碟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舷丹,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颜凯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年症杏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厉颤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡精肃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出筐眷,到底是詐尸還是另有隱情习柠,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布武翎,位于F島的核電站溶锭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏垫毙。R本人自食惡果不足惜拱绑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一欺栗、第九天 我趴在偏房一處隱蔽的房頂上張望征峦。 院中可真熱鬧,春花似錦栏笆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丁眼。三九已至,卻和暖如春藐守,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背乾蓬。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工慎恒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人族奢。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓越走,卻偏偏與公主長(zhǎng)得像靠欢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骡澈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • 第一篇 語言 第0章 序言 Lua僅讓你用少量的代碼解決關(guān)鍵問題肋殴。 Lua所提供的機(jī)制是C不擅長(zhǎng)的:高級(jí)語言坦弟,動(dòng)態(tài)...
    testfor閱讀 2,651評(píng)論 1 7
  • C API 云風(fēng)Blog:Lua C API 的正確用法 C讀取和調(diào)用Lua文件的庫(kù):lua.h, lauxlib...
    SysuYe閱讀 5,631評(píng)論 2 10
  • lua C api PS:這里是默認(rèn)我已經(jīng)學(xué)完了lua腳本的基本知識(shí)(包括table酿傍,元表,函數(shù)氯析,基本庫(kù)莺褒, 文件i...
    綠箭ML閱讀 3,410評(píng)論 0 1
  • 月兒遵岩,那時(shí)炎熱剛剛退去 雨滴翻山越水而來,在我的窗前不絕清唱 窗戶自然是開著的。還有伸長(zhǎng)了等待傾聽的耳朵 月兒扁达,在...
    楊昊田閱讀 584評(píng)論 4 12