lua與c交互

Lua_State 動態結構

這個結構是虛擬機運行起來最重要的結構體

用 Lual_newstate 創建一個新的環境
lualib.h 定義了打開標準庫的函數 Lual_openlibs 可以打開所有的標準庫
創建好狀態 在加載了標準庫以後就能解釋用戶的輸入了。

Lua 和 c 的交互全在虛擬站裏面進行。
虛擬棧解決了lia和c 的兩大差異
1>lua的垃圾收集
2>c是靜態類型 lua是動態類型。

lua_loadbuffer() 函數來編譯用戶輸入的每行內容 沒有錯誤 返回0 並向棧中壓入編譯好的程序塊。
調用lua_pcall 將程序塊從棧中彈出。在保護模式中運行。返回0無錯誤。出錯會像虛擬站裏面壓入錯誤信息。
lua_pop可以將站裏的信息刪除。lua_tostring獲得這條信息。。

如果將lua作爲c來編譯 並在c++中使用,可以包含 lua.hpp 代替lua.h
lua.hpp定義 :
extern “c”{#include “lua.h”}

c包含lua類型

lua的函數參數是沒有類型的 c是要固定類型的 這個可以用union來解決
聲明一個 union 裏面裝着 所有的lua類型
例如:settable(lua_value a,lua_value k, lua_value v);     //a 是表名 k是鍵值 v是實值
這樣有兩個缺點 :
1>不能將這樣的東西 映射到其他的語言
2>lua的垃圾清理機制 如果用c的這個保存變量 lua的垃圾清理檢測不到 然後把他們當成垃圾了,然後給清理了就好了。

所以 並沒有用這樣的方式實現, 而是使用了一種特殊的虛擬站 實現。
棧裏面的每一個元素都能保存任何類型的lua值。要獲取lua值的時候就調用一個lua 的 API函數。

lua將指定的值壓入棧中。將一個值傳給lua時候,先將值壓入棧。然後調用lua API lua就可以獲得值 並從棧中彈出
爲了將c類型的值壓入棧,或者從棧中獲取不同類型的值,就爲每個類型定義一個特定的函數。棧有lua管理 可以共垃圾收集器使用。
lua_loadbuffer將編譯好的程序塊或者錯誤信息留在棧中。

lua_pcall會調用棧中的一個函數

lua 按照LIFO規範來操作棧,當調用lua時候,lua只會改變棧頂。

c代碼擁有更大的自由度,比如插入刪除遍歷等等。

壓入棧函數 API
lua_pushnil(lua_state *L);                  //壓入nil

lua_pushboolean(lua_state *L,int bool);           //壓入bool         

lua_pushnumer(lua_state *L,lua_Number n);         //壓入雙精度

lua_pushinteger(lua_state *L,lua_Integeter);         //壓入整數

lua_pushlstring(lua_state L,const char str,size_t len);    //壓入定長字符串

lua_pushstring(lua_state *L,const char *str);         //壓入結尾是0的字符串

lua_Number lua_Integer是lua的兩個類型 吧 對應小數整數

lua會爲字符串創建副本而不會持有指針 所以放心操作。

lua_checkStack(lua_state *L,int sz)     //檢測是否有足夠的空閒。 4 - 2 80 - 40 240 -120 -3

錯誤處理

平常代碼是 在不保護模式下進行的

當亂髮現了例如”內存不足”這樣的錯誤的時候,不會處理,而是調用一個“緊急”函數,打不過嘎不是關於發佈關於三皈依,lua就結束了,可以通過lua_aparic設置自己的”緊急”函數。

lual_newstate,lua_load,lua_pcall,lua_close是安全的,不會跑出異常。

如果發生了內存的錯誤 又不想結束程序

1>設置一個”緊急”函數,不把控制權返回給lua

2>讓代碼在“保護模式”下運行

大多數採用2 的做法 獨愛踢不過lua_pcall來運行lua代碼 這些lua代碼就是運行在保護模式下的。

在爲lua 編寫函數的時候 只有一種標準的錯誤處理方法。當c函數檢測到一個錯誤時候 就用該調用lua_error .lua_error會清理lua中所有要清理的東西,然後跳到之前要執行的Lua_pcall,並附上一條錯誤信息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章