c++17进阶(2)-Lua扩展(1)
Lua的C API,也就是主機(jī)程序可用于與Lua通信的C函數(shù)集。所有API函數(shù)以及相關(guān)的類型和常量都在頭文件lua.h中聲明。
API中的任何功能(函數(shù))都可以作為宏來(lái)提供。除非另有說(shuō)明,所有這樣的宏都只使用它們的每個(gè)參數(shù)一次(除了第一個(gè)參數(shù),它總是一個(gè)Lua狀態(tài)),因此不會(huì)產(chǎn)生任何隱藏的副作用。 但要注意,與大多數(shù)C庫(kù)一樣,Lua API函數(shù)不會(huì)檢查其參數(shù)的有效性或一致性,可通過(guò)使用定義的宏LUA_USE_APICHECK編譯Lua改變這種行為。
Lua庫(kù)是完全可重入的:它沒(méi)有全局變量。它將需要的所有信息保存在一個(gè)動(dòng)態(tài)結(jié)構(gòu)中,稱為L(zhǎng)ua狀態(tài)。 每個(gè)Lua狀態(tài)都有一個(gè)或多個(gè)線程,它們對(duì)應(yīng)于獨(dú)立的、協(xié)作的執(zhí)行行。類型lua_State(盡管名稱不同)指的是線程(間接地,通過(guò)線程,它也引用與線程相關(guān)聯(lián)的Lua狀態(tài))。指向線程的指針必須作為第一個(gè)參數(shù)傳遞給庫(kù)中的每個(gè)函數(shù),lua_newstate除外,它從頭創(chuàng)建一個(gè)Lua狀態(tài),并返回指向處于新?tīng)顟B(tài)的主線程的指針。
當(dāng)與Lua API交互時(shí),有責(zé)任確保一致性,一定妥善控制堆棧溢出。當(dāng)調(diào)用任何API函數(shù)時(shí),必須確保堆棧有足夠的空間來(lái)容納結(jié)果。但是,當(dāng)你調(diào)用一個(gè)沒(méi)有固定數(shù)量結(jié)果的Lua函數(shù)時(shí)(參見(jiàn)lua_call), Lua會(huì)確保堆棧有足夠的空間容納所有結(jié)果,它不確保任何額外的空間。因此,在這樣一個(gè)調(diào)用之后將任何東西壓入堆棧之前,應(yīng)該使用lua_checkstack。
API中接收堆棧索引的任何函數(shù)只能使用有效索引或可接受索引。
有效索引是指存儲(chǔ)可修改Lua值的位置的索引。它由1和棧頂之間的堆棧索引(1≤abs(index)≤top)加上偽索引組成,偽索引表示一些C代碼可以訪問(wèn)但不在棧內(nèi)的位置。偽索引用于訪問(wèn)注冊(cè)表(見(jiàn)§4.3)和C函數(shù)的上值(見(jiàn)§4.2)。
不需要特定的可變位置而只需要一個(gè)值的函數(shù)(例如,查詢函數(shù))可以使用可接受的索引來(lái)調(diào)用。一個(gè)可接受的索引可以是任何有效索引,但也可以是堆棧頂部之后為堆棧分配的空間內(nèi)的任何正索引,即堆棧大小之前的索引。(注意,0永遠(yuǎn)都不是一個(gè)可接受的索引。)向上值的索引(見(jiàn)§4.2)大于當(dāng)前C函數(shù)中向上值的實(shí)際數(shù)目也是可以接受的(但無(wú)效)。除非另有說(shuō)明,否則API中的函數(shù)都使用可接受的索引。
可接受的索引可以避免在查詢堆棧時(shí)對(duì)堆棧頂部進(jìn)行額外的測(cè)試。例如,一個(gè)C函數(shù)可以查詢它的第三個(gè)參數(shù),而不需要檢查是否有第三個(gè)參數(shù),也就是說(shuō),不需要檢查3是否是一個(gè)有效的索引。
對(duì)于可以使用可接受索引調(diào)用的函數(shù),任何無(wú)效索引都被視為包含虛擬類型LUA_TNONE的值,該值的行為類似于nil值。
總結(jié)
以上是生活随笔為你收集整理的c++17进阶(2)-Lua扩展(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spring 事务方法与非事务方法相互调
- 下一篇: c++17进阶(3)-Boehm GC垃