lua學(xué)習(xí)筆記3-c調(diào)用lua

lua C api

PS:這里是默認(rèn)我已經(jīng)學(xué)完了lua腳本的基本知識(包括table氨淌,元表,函數(shù)村视,基本庫官套, 文件io,庫導(dǎo)入等等)

lua是c寫的蚁孔,無論是lua調(diào)用c還是c調(diào)用lua都非常容易奶赔,以下是基于文檔做的一些學(xué)習(xí)筆記,在文檔的索引可以快速找到api的名稱方便參考杠氢,文檔地址如下:
官網(wǎng)5.3文檔:http://www.lua.org/manual/5.3/#index
中文文檔:http://www.runoob.com/manual/lua53doc/contents.html#index

文檔包括兩部分站刑,一部分是介紹lua的語法,以及一些注(keng)意(die)事項,比如其中說到空字符串和0都被認(rèn)為是true鼻百,恩绞旅,要注意(MDZZ),感覺lua的強(qiáng)大之處在于他的table(手動咸魚)温艇,下面開始修仙因悲,下面通過問答的方式給自己學(xué)習(xí)lua做一些筆記,在此之前勺爱,先編譯lua晃琳,我們到官網(wǎng)可以下載lua的源碼

源碼下載頁面:http://www.lua.org/download.html
5.3源碼下載:http://www.lua.org/ftp/lua-5.3.4.tar.gz

lua源碼非常小,很容易編譯,windows下卫旱,裝個Mingw即可用make編譯人灼,以下是linux的

1.下載解壓源碼

wget http://www.lua.org/ftp/lua-5.3.4.tar.gz
tar -xzvf lua-5.3.4.tar.gz
~/local/lua/lua-5.3.4$ make
Please do 'make PLATFORM' where PLATFORM is one of these:
   aix bsd c89 freebsd generic linux macosx mingw posix solaris
See doc/readme.html for complete instructions.

上面提示指定編譯選項,如果是windows下用Mingw的顾翼,就make -j12 mingw, -j12是多線程編譯投放,分12個線程編譯,現(xiàn)在是debian暴构,可以選擇posix跪呈,如果提示缺少一些庫段磨,使用apt-get 安裝即可

make -j12 posix

編譯成功后取逾,在src文件生成一個lua(lua解釋器),luac(lua腳本編譯器),以及靜態(tài)庫liblua.a,c調(diào)用lua的時候苹支,現(xiàn)在是用靜態(tài)庫砾隅,現(xiàn)在把以下文件復(fù)制到項目目錄下
頭文件:lua.h lualib.h lauxlib.h luaconf.h
靜態(tài)庫文件:liblua.a
我的項目目錄為:~/project/lua
我把頭文件放置在~/project/lua/include
靜態(tài)庫文件放在~/project/lua/lib

以下所有的操作都是在項目目錄(用$PRO_HOME描述這個目錄)


1.c是如何調(diào)用lua寫的代碼的?

1.首先了解债蜜,lua在c代碼中是如何“工作”的晴埂,在c中要調(diào)用lua,首先我得創(chuàng)建一個lua狀態(tài)機(jī)(lua_State)
文件$PRO_HOME/main.c

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

int main(void)
{
  //創(chuàng)建一個lua狀態(tài)機(jī)
  lua_State *L  = luaL_newstate();
  //銷毀這貨
  lua_close(L);
  return 0;
}

然后嘗試編譯這個源文件

$gcc -I ../include -c main.c
$gcc -lm -o main main.o ../lib/liblua.a

編譯成功說明配置沒有問題

c調(diào)用lua代碼寻定,首先要學(xué)會怎么把lua代碼“翻譯”成c的代碼儒洛,先不著急如何把lua代碼加載到lua狀態(tài)機(jī)運(yùn)行,先了解下它是怎么運(yùn)行的狼速,根據(jù)文檔參考琅锻,寫以下一段代碼

-- a是一個全局變量
a="測試"
print(a)

a是一個全局變量,在lua中向胡,無非在維護(hù)一個堆棧stack和一個環(huán)境表_G(暫時理解)
那么用c怎么寫呢恼蓬?
1.創(chuàng)建一個狀態(tài)機(jī)(lua_State),加載基本庫(luaL_openlibs())
2.把字符串“測試”壓入堆棧(lua_pushstring)
3.把這個字符串彈出僵芹,設(shè)置為global处硬,名稱為a(lua_setglobal())
4.從全局變量中,把print函數(shù)壓棧(lua_getglobal())
5.把參數(shù)a從全局變量中壓棧(lua_getglobal())
6.調(diào)用lua_call執(zhí)行函數(shù)

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

int main(void)
{
    lua_State *L = luaL_newstate();
   //加載基本庫(print在其中)
    luaL_openlibs(L);
    //這里相當(dāng)于設(shè)置全局變量a="測試"
    lua_pushstring(L,"測試");
    lua_setglobal(L,"a");
    //print函數(shù)壓棧
    lua_getglobal(L,"print");
    //參數(shù)壓棧yiban
    lua_getglobal(L,"a");
    //調(diào)用函數(shù),1個參數(shù)拇派,0個返回值
    lua_call(L,1,0);
    lua_close(L);
    return 0;
}

小總結(jié):

在lua 的 C api中荷辕,
數(shù)據(jù)類型有:
lua_Integer 整形
lua_Number 默認(rèn)對應(yīng)的是C double
lua_Unsigned 無符號整形

字符串、布爾型或者是lua的table之類的件豌,都是不能直接“拿出來”的
如果要操作桐腌,設(shè)置某某某的變量,可以通過lua_pushxxxx來把對應(yīng)的數(shù)據(jù)類型的變量的值壓入堆棧苟径,如果案站,要把變量設(shè)置為一個全局變量,就把它設(shè)置為global(lua_setglobal()),lua_setglobal會把棧頂?shù)脑貜棾鲶⊙危≡O(shè)置到環(huán)境表承边,詳情查看文檔,

關(guān)于堆棧

lua的堆棧是lua自己實(shí)現(xiàn)的一個數(shù)據(jù)結(jié)構(gòu)石挂,并不是c語言執(zhí)行時的那個堆棧博助,這個堆棧,由棧底往棧頂數(shù)痹愚,元素的序號是1 2 3 4 5...富岳,這是它的絕對索引的方式,還有它支持負(fù)索引拯腮,也就是參考點(diǎn)是棧頂窖式,而不是棧底,比如-1代表的是棧頂?shù)脑兀?2代表棧頂?shù)南乱粋€元素

對于堆棧的操作有:
1.獲取棧頂?shù)乃饕?lua_gettop(L)(這個值动壤,可以當(dāng)做是棧元素個數(shù))

2.把數(shù)據(jù)壓棧(lua_pushxxx萝喘,根據(jù)壓入的數(shù)據(jù)類型不一樣,有對應(yīng)有一系列的操作函數(shù),例如琼懊,lua_pushstring(L,"測試"),把字符串壓入阁簸,詳情看文檔lua_pushxxxx),又或者是

3.把堆棧的元素“讀取”出來哼丈,lua_toxxxx,就可以不彈出堆棧中的數(shù)據(jù)启妹,把它轉(zhuǎn)換成c的數(shù)據(jù)類型,例如:lua_tolstring,注意醉旦,這個返回值是const類型饶米,也就是說你不能對他進(jìn)行更改,如果要做其他用途髓抑,你需要
把他copy出來

4.更改元素在堆棧中的位置

5.lua有垃圾回收機(jī)制GC咙崎,一般不用擔(dān)心內(nèi)存釋放的問題


2.如何在lua狀態(tài)機(jī)中執(zhí)行一個c寫的函數(shù)?

剛剛已經(jīng)學(xué)了吨拍,如何在c中褪猛,“執(zhí)行”lua,這個print函數(shù)他已經(jīng)實(shí)現(xiàn)了羹饰,但是我們自己怎么實(shí)現(xiàn)一個函數(shù)伊滋,然后在lua中調(diào)用呢?
這個函數(shù)可以是
1.lua寫的函數(shù)
2.c寫的可以讓lua識別的函數(shù)
我們先來搞第二種,程序還是在原來的基礎(chǔ)上進(jìn)行擴(kuò)充

我們把print換成我們自己實(shí)現(xiàn)的一個函數(shù)队秩,這個函數(shù)在lua里叫print2,它比較簡單笑旺,只能接受一個參數(shù)掂恕,不做任何檢查该押,也不做任何的錯誤的處理

lua注冊的函數(shù)的類型是:
static int fun(lua_State *L);
返回值是這個函數(shù)的返回值個數(shù)(因為lua支持多個返回值,執(zhí)行完畢后骑篙,把返回值依次壓棧,然后返回返回值個數(shù)就行了)乌妙,調(diào)用結(jié)束后使兔,堆棧中剩下的是fun的返回值(如果有返回值,并且按照順序壓棧)

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

static int print2(lua_State *L)
{
   const char * s = luaL_optlstring (L,1,"啥都沒",NULL);  //獲取函數(shù)調(diào)用時第1個參數(shù)為字符串藤韵,如果參數(shù)不存在或者是nil就返回“啥都沒”虐沥,并且把長度放在第四個參數(shù)(這里設(shè)置為NULL,不獲取長度),
  printf("這是:%s\n",s);
  return 0;  //返回值個數(shù)為0
}

int main(void)
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);      //加載基本庫(print在其中)
    //這里相當(dāng)于設(shè)置全局變量a=image.png"測試"
    lua_pushstring(L,"測試");
    lua_setglobal(L,"a");
  
  //注冊這個函數(shù)到全局表 
    lua_register(L,"print2",print2);

    lua_getglobal(L,"print2");      //把這個函數(shù)從全局表中壓棧
    lua_getglobal(L,"a");         //參數(shù)壓棧
    lua_call(L,1,0);         //調(diào)用函數(shù),1個參數(shù)泽艘,0個返回值
    lua_close(L);          //關(guān)閉狀態(tài)機(jī)
    return 0;
}

未完待續(xù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末欲险,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子匹涮,更是在濱河造成了極大的恐慌天试,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焕盟,死亡現(xiàn)場離奇詭異秋秤,居然都是意外死亡宏粤,警方通過查閱死者的電腦和手機(jī)脚翘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绍哎,“玉大人来农,你說我怎么就攤上這事〕缪撸” “怎么了沃于?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長海诲。 經(jīng)常有香客問我繁莹,道長,這世上最難降的妖魔是什么特幔? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任咨演,我火速辦了婚禮,結(jié)果婚禮上蚯斯,老公的妹妹穿的比我還像新娘薄风。我一直安慰自己,他們只是感情好拍嵌,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布遭赂。 她就那樣靜靜地躺著,像睡著了一般横辆。 火紅的嫁衣襯著肌膚如雪撇他。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音困肩,去河邊找鬼募疮。 笑死,一個胖子當(dāng)著我的面吹牛僻弹,可吹牛的內(nèi)容都是我干的阿浓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼蹋绽,長吁一口氣:“原來是場噩夢啊……” “哼芭毙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起卸耘,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤退敦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蚣抗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侈百,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年翰铡,在試婚紗的時候發(fā)現(xiàn)自己被綠了钝域。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡锭魔,死狀恐怖例证,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情迷捧,我是刑警寧澤织咧,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站漠秋,受9級特大地震影響笙蒙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜庆锦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一捅位、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肥荔,春花似錦绿渣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至誉帅,卻和暖如春淀散,著一層夾襖步出監(jiān)牢的瞬間右莱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工档插, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慢蜓,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓郭膛,卻偏偏與公主長得像晨抡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子则剃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

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

  • 原文地址:C語言函數(shù)調(diào)用棧(一)C語言函數(shù)調(diào)用棧(二) 0 引言 程序的執(zhí)行過程可看作連續(xù)的函數(shù)調(diào)用耘柱。當(dāng)一個函數(shù)執(zhí)...
    小豬啊嗚閱讀 4,590評論 1 19
  • 當(dāng)在Lua和C之間交換數(shù)據(jù)時主要的問題是自動回收與手動回收內(nèi)存管理的不一致。因此棍现,Lua 用一個抽象的棧在Lua與...
    luffier閱讀 2,632評論 0 3
  • 第一篇 語言 第0章 序言 Lua僅讓你用少量的代碼解決關(guān)鍵問題调煎。 Lua所提供的機(jī)制是C不擅長的:高級語言,動態(tài)...
    testfor閱讀 2,651評論 1 7
  • 1. 寫在前面 很多時候我們都需要借助一些腳本語言來為我們實(shí)現(xiàn)一些動態(tài)的配置己肮,那么就會涉及到如何讓腳本語言跟原生語...
    杰嗒嗒的阿杰閱讀 3,423評論 9 31
  • 昨天和孩子爸討論了孩子教育的問題士袄。 這次是有效的一次溝通。 孩子的爸爸比我谎僻,有耐心娄柳,我把孩子學(xué)過的和要預(yù)習(xí)的數(shù)學(xué)和...
    里娃閱讀 122評論 0 0