Lua擴充套件

2021-08-02 14:21:15 字數 4167 閱讀 2140

lua作為配置檔案使用-- win_conf.lua 定義視窗大小

width = 200

height = 300

使用lua api分析這個檔案,並獲取width和height
void

load

(lua_state*l,const

char*fname,int *w,int*h)

table操作

lua 5.1提供了lua_getfiled和lua_setfield函式,lua5.1之前可以使用下面的方式,操作table

假設table在棧頂

-- win_conf.lua

blue =

background = blue

...lua_getglobal(l,"background");

if(!lua_istable(l,-1))

error(l,"'background' is not a table")

red = getfield(l,"r")

.../*假設table在棧頂*/

int getfield(lua_state*l,const

char* key)

/*table在棧頂*/

void setfield(lua_state* l,const

char* key,int value)

c呼叫lua
-- f.lua

function f(x,y)

return x+y

end-- f.c

double f(double x,double y)

if(!lua_isnumber(l,-1)) error(l,"function 'f' must return a number");

z = lua_tonumber(l,-1);

lua_pop(l,1); /*彈出返回值(彈出1個元素)*/

return z;

}

lua呼叫c
-- l_sin.c

static in l_sin

(lua_state* l)

//所有註冊到lua中函式原型都如下(lua.h中定義)

typedef

int(*lua_cfunction)

(lua_state*)

;//這個函式無須再壓入結果前清空棧。在它返回後,lua會自動清空棧中結果之下的內容

//lua使用了l_sin之前必須先註冊,使用lua_pushcfunction來進行註冊

lua_pushcfuction(l,l_sin);

lua_setglobal(l,"mysin");

c模組

當用c函式擴充套件lua時,最好將**設計為乙個c模組。輔助庫提供了乙個函式lual_register,這個函式接受一些c函式及名稱,並將這些函式註冊到乙個與模組同名的table中去。

//宣告乙個陣列(包含模組中所有的函式和名稱)

static

const

struct lual_reg mylib = ,

/*結尾*/

};//註冊函式

intluaopen_mylib

(lua_state* l)

--lua中使用(自動載入mylib.so)

require("mylib")

編寫函式的技術:陣列操作,字串操作,狀態儲存

陣列操作:針對陣列型的table

//index為table在棧中的位置,key為陣列索引

//等價於 lus_pushnumber(l,key);lua_rawget(l,index);

void

lua_rawgeti

(lua_state* l,int index,int key)

;//等價於 lus_pushnumber(l,key);lua_insert(l,-2);lua_rawset(l,index);

void

lua_rawseti

(lua_state* l,int index,int key)

;

字串操作
//把字串的子串([i,j])傳入lua

lua_pushlstring(l,s+i,j-i+1)

//l_split ("hi,ho,three")->

static

intl_split

(lua_state*l)

lua_pushlstring(l,s);//壓入最後乙個子串

lua_rawseti(l,-2,i);

return

1;}

c函式中儲存狀態

登錄檔(registry)

登錄檔總是位於乙個"偽索引"上,這個索引由lua_registryindex定義,這個索引上有乙個table。

登錄檔是乙個普通的lua table,可以用任何lua值(除了nil)來索引它。lua api中的大多數函式都接受偽索引,但是lua_remove,lua_insert這種操作棧本身的函式只能用普通索引。獲得登錄檔中key為"key"的值

lua_getfield(l,lua_registryindex,"key");
所有的c模組共享乙個登錄檔,請注意key不要衝突。可以使用uuid做key,定義特定的巨集來定義庫。

另外登錄檔中不可以使用數字做key,這種key被「引用系統」所保留。這個系統是有輔助系統中的一系列函式組成,它可以向乙個table儲存value時,忽略如何建立乙個唯一的key

int r = lual_ref(l,lua_registr)

//r 即為引用,當需要使用乙個c變數儲存乙個指向lua值得引用時,就需要使用引用系統

lua_rawgeti(l,lua_regestryindex,r);//將r關聯的值壓入棧

lual_unref(l,lua_regstryindex,r);//釋放引用和其值,再呼叫lual_ref會返回相同的引用

//引用系統將nil視為一種特殊情況。為乙個nil值呼叫lual_ref是,不會建立新的應用,返回乙個常量lua_refnil

lua_unref(l,lua_regstryindex,lua_refnil);//無效果

lua_rawgeti(l,lua_regstryindex,lua_refnil);//會壓入nil

c 函式環境(lua5.1特性)

環境table的偽索引是lua_environindex。盡可能的使用環境表來代替登錄檔,出發需要在不同模組間共享資料。

int

luaopen_foo(lua_state*l)

upvalue:閉包值儲存,類似於c函式內靜態變數機制.

每當在lua中建立函式時,可以將任意數量的upvalue與這個函式關聯。每個upvalue都可以儲存乙個lua值。以後,呼叫這個函式時,可以同偽索引來訪問這些upvalue。將這種c 函式與upvalue的關聯稱為closure.

static

intcounter

(lua_state*l)

;//每次呼叫返回乙個新的賬號函式

intnewcounter

(lua_state*l)

//counter的定義

static

intcounter

(lua_state*l)

//lua_upvalueindex(1)可以生成乙個upvalue的偽索引,這個索引可以像其他棧索引一樣使用

高階用法(元組的c實現)
-- lua

x = tuple.new(10,"hi",{},3)

print

(x(1)) -->

10print

(x(2)) -->hi

print

(x()) -->

10,hi table:0x...,3

-- lua_tuple.c

int t_tuple(lua_state*l)

else

}int t_new(lua_state* l)

static const struct lual_reg tuplelib = ,

};int luaopen_tuple(lua_state*l)

章魚lua擴充套件模組

1.安裝ndk並設定環境變數 2.切換到project jni目錄下執行ndk build 注意 需要把so放到某個目錄中,我這裡是 data local tmp 例如 adb push mytestlib.so data local tmp lua核心api宣告 include lua.h lua...

Linux下Lua擴充套件so

include include include include include include include include include include include lua.h include lualib.h include lauxlib.h 庫 open 函式的前置宣告 int lu...

lua安裝luasql擴充套件模組

使用lua sql 安裝lua日誌模組 結束語使用lua程式設計過程中不可避免的會用到mysql等資料庫,進行資料庫操作lua有luasql,各個資料庫操作的介面統一,用起來比較方便,但是這貨安裝起來有時候遇到問題會比較麻煩,下面介紹如何安裝luasql 1.安裝lua 2.安裝luarocks 3...