csdn學習筆記:lua於c/c++互動
lua使用一個虛擬棧來和c互傳值。棧上的每一個元素都是一個lua值
所有對棧的api查詢操作都不嚴格遵循棧的操作規則。而是可以用一個索引來指向棧上的任何元素;正的索引指的棧上的絕對位置(從1開始);負的索引則指從棧頂開始的偏移量。
展開來說,如果堆疊有n個元素,那麼索引1表示第一個元素(也就是最先被壓棧的元素)而索引n則是指最後一個元素;索引-1也是指向最後一個元素(即棧頂的元素),索引-n是指第一個元素
push functions (C -> stack)
void lua_pushnil (lua_State * L);
void lua_pushboolean (lua_State * L, int bool); void lua_pushnumber (lua_State * L, lua_Number n);
void lua_pushinteger (lua_State * L, lua_Integer n);
void lua_pushlstring (lua_State * L, const char * s, size_t len); void lua_pushstring (lua_State * L, const char * s);
set function (stack ->lua)
void (lua_setglobal) (lua_State * L, const char * name);
void (lua_settable) (lua_State * L, int idx);
void (lua_setfield) (lua_State * L, int idx, const char * k);
void (lua_seti) (lua_State * L, int idx, lua_Integer n);
void (lua_rawset)
void (lua_rawseti) (lua_State * L, int idx, lua_Integer n);
void (lua_rawsetp) (lua_State * L, int idx, const void * p);
int (lua_setmetatable) (lua_State * L, int objindex);
void (lua_setuservalue) (lua_State * L, int idx);
get functions (Lua -> stack)
int (lua_getglobal) (lua_State *L, const char *name);
int (lua_gettable) (lua_State *L, int idx);
int (lua_getfield) (lua_State *L, int idx, const char *k);
int (lua_geti) (lua_State *L, int idx, lua_Integer n);
int (lua_rawget) (lua_State *L, int idx);
int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
int (lua_rawgetp) (lua_State *L, int idx, const void *p);
void (lua_createtable) (lua_State *L, int narr, int nrec);
void *(lua_newuserdata) (lua_State *L, size_t sz);
int (lua_getmetatable) (lua_State *L, int objindex);
int (lua_getuservalue) (lua_State *L, int idx);
access functions (stack -> C)不出棧
int (lua_isnumber) (lua_State *L, int idx);
int (lua_isstring) (lua_State *L, int idx);
int (lua_iscfunction) (lua_State *L, int idx);
int (lua_isinteger) (lua_State *L, int idx);
int (lua_isuserdata) (lua_State *L, int idx);
int (lua_type) (lua_State *L, int idx);
const char *(lua_typename) (lua_State *L, int tp);
lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
int (lua_toboolean) (lua_State *L, int idx);
const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
size_t (lua_rawlen) (lua_State *L, int idx);
lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
API常用介面
LUA_API | desc |
int lua_gettop(lua_State *L) |
|
void lua_settop(lua_State *L, int index) |
|
lua_settop(L, 0); |
// 清空棧。 |
void lua_pushvalue (lua_State *L, int index); |
|
void lua_replace(lua_State *L, int index) |
|
void lua_rotate (lua_State *L, int index, int n); |
* 把從 idx 開始到棧頂的元素輪轉 n 個位置。 對於 n 為正數時,輪轉方向是向棧頂的; 當 n * 為負數時,向棧底方向輪轉 -n 個位置。 n 的絕對值不可以比參於輪轉的切片長度大。 |
常用巨集
#define lua_pop(L,n) lua_settop(L, -(n) - 1) |
彈出從棧頂開始的幾個索引 |
#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) |
移除棧中索引"index"處的元素, 該元素之上的所有元素下移。 從給定有效索引處移除一個元素, 把這個索引之上的所有元素移下來填補上這個空隙 |
#define lua_insert(L,idx) lua_rotate(L, (idx), 1) |
將棧頂元素移動到索引"index"處, 索引"index"(含)之上的所有元素上移。 |
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static void stackDump(lua_State* L){
static int count = 0;
printf("begin dump lua stack %d\n", count);
int i = 0;
int top = lua_gettop(L);
for (i = top; i >= 1; --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("\nend dump lua stack %d \n", count++);
}
int main(){
//printf("hello c\n");
lua_State* L = luaL_newstate(); //建立一個lua虛擬機器(lua上下文),類似於指標
luaL_openlibs(L);
lua_pushinteger(L, 21);
lua_pushinteger(L, 22);
lua_pushinteger(L, 23);
stackDump(L); //列印棧上的內容
//int lua_gettop(lua_State* L);
//printf("stack size = %d\n", lua_gettop(L));
//stack資料為23,22,21
//lua_settop(L, 5); //設定索引5為棧頂索引,沒有資料為nil
//stackDump(L); //輸出為nil,nil,23,22,21
//lua_settop(L, -2); //負數按負數索引走,-2表示從棧頂開始的第二個元素
//stackDump(L);
//stack資料為23,22,21
//lua_pushvalue(L, 2); //把索引2的資料複製到棧頂,
//stackDump(L); //輸出22,23,22,21
lua_pushinteger(L, 24);
//stack資料為24,23,22,21
//lua_replace(L, 2); //將棧頂元素移動到索引2處,(棧頂出棧,覆蓋了索引2的元素)
//stackDump(L); //輸出為23,24,21
//stack資料為24,23,22,21
//lua_rotate(L, 2, 1);
//把從idx開始到棧頂的元素輪轉n個位置。n為正數,輪轉方向是向棧頂,
//當n為負數時,向棧底方向輪轉-n個位置,n的絕對值不可以比參與輪轉的切片長度大
//stackDump(L); //輸出23,22,24,21
//lua_rotate(L, 2, -1);
//把從idx開始到棧頂的元素輪轉n個位置。n為正數,輪轉方向是向棧頂,
//當n為負數時,向棧底方向輪轉-n個位置,n的絕對值不可以比參與輪轉的切片長度大
//stackDump(L); //輸出22,24,23,21
//lua_rotate(L, 2, 2);
//stackDump(L); //輸出22,24,23,21
//stack資料為24,23,22,21,如果想把22刪除掉
/*lua_rotate(L, 2, 2);
lua_settop(L, -2);
stackDump(L);*/
//end
//##########常用巨集#############
////#define lua_pop(L,n) lua_settop(L,-(n)-1)
//stack資料為24,23,22,21
//lua_pop(L, 3); //彈出3個元素
//stackDump(L); //輸出21
//lua_pop(L, -1); //等價於lua_settop(L,0); 清空棧,儘量不要用負數
//stack資料為24,23,22,21
//lua_remove(L, 2); //remove第二個索引的元素
//stackDump(L); //輸出24 23 21
//stack資料為24,23,22,21
//lua_insert(L, 2); //把棧頂元素插入到索引位置,其他元素上移,和lua_rotate(L, 2, 1);效果一樣
stackDump(L); //輸出23,22,24,21
lua_close(L);
system("pause");
return 0;
}