獲取table字段值
想要獲取table字段的值仪媒,首先需要確定table在棧中的位置,知道了table的索引之后谢鹊,在通過lua提供的函數(shù)來獲取字段值
int lua_getfield (lua_State *L, int idx, const char *k)
示例:
test_table.lua
background = {r=0.30, g=0.10,b=0}
main.cc
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#include "lua.h"
#include "lauxlib.h"
}
#endif // __cplusplus
#define MAX_COLOR 255
void error(lua_State *L, const char* fmt, ...) {
va_list argp;
va_start(argp, fmt);
vfprintf(stderr, fmt, argp);
va_end(argp);
lua_close(L);
exit(EXIT_FAILURE);
}
int getfield(lua_State* L, int index, const char* key) {
int result;
lua_getfield(L, index, key);//table 中的key會(huì)入棧 table 索引此時(shí)會(huì)變成 -2
if (!lua_isnumber(L, -1)) {
error(L, "invalid bakcground color");
}
result = (int)(lua_tonumber(L, -1) * MAX_COLOR);
lua_pop(L, 1); //從棧彈出一個(gè)元素算吩,即剛剛放入的 table的key對(duì)應(yīng)的值
return result;
}
void load(lua_State* L, const char* fname) {
if (luaL_loadfile(L, fname) || lua_pcall(L, 0, 0, 0)) {
//luaL_loadfile\lua_pcall 發(fā)生錯(cuò)誤,兩個(gè)函數(shù)都會(huì)把錯(cuò)誤消息壓入棧佃扼,并返回一個(gè)非零的錯(cuò)誤代碼偎巢,可以通過lua_tostring獲得錯(cuò)誤信息
error(L, "error cannot run config file:%s\n", lua_tostring(L, -1));
}
lua_getglobal(L, "background"); //將lua腳本中的全局變量 background 入棧
int red = getfield(L, -1, "r");
int green = getfield(L,-1, "g");
int blue = getfield(L,-1, "b");
printf("red =%d , green=%d, blue=%d\n", red, green, blue);
}
int main() {
lua_State* L = luaL_newstate();
int weight = 0;
int height = 0;
load(L, "./load_table.lua");
lua_close(L);
system("pause");
}
設(shè)置table的key的值
設(shè)置table的key的值需要用到lua_setfield函數(shù), 同樣的使用這個(gè)函數(shù)時(shí),也需要知道 table 的索引
LUA_API void lua_setfield (lua_State *L, int idx, const char *k);
但是這里用到了另外兩個(gè)函數(shù)
void lua_newtable(lua_State *L); //實(shí)際上是個(gè)宏兼耀, 創(chuàng)建一個(gè)新的table, 并將其壓入棧
void lua_setglobal (lua_State *L, const char *name) //給棧頂變量設(shè)置名字,并把棧頂元素彈出
示例代碼:
main.cc
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#include "lua.h"
#include "lauxlib.h"
}
#endif // __cplusplus
#define MAX_COLOR 255
static void stack_dump(lua_State *L) {
int i;
int top = lua_gettop(L);//
printf("stack len:%d ", top);
for (i = 1; i <= top; 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(" ");
}
printf("\n");
}
void error(lua_State *L, const char* fmt, ...) {
va_list argp;
va_start(argp, fmt);
vfprintf(stderr, fmt, argp);
va_end(argp);
lua_close(L);
exit(EXIT_FAILURE);
}
struct ColorTable {
const char *name;
unsigned char red, green, blue;
};
int getfield(lua_State* L, int index, const char* key) {
int result;
lua_getfield(L, index, key);//table 中的key會(huì)入棧 table 索引此時(shí)會(huì)變成 -2
if (!lua_isnumber(L, -1)) {
error(L, "invalid bakcground color");
}
result = (int)(lua_tonumber(L, -1) * MAX_COLOR);
lua_pop(L, 1); //從棧彈出一個(gè)元素压昼,即剛剛放入的 table的key對(duì)應(yīng)的值
return result;
}
void setfield(lua_State *L, const char *key, int value) {
lua_pushnumber(L, (double)value / MAX_COLOR);
lua_setfield(L, -2, key);
}
void setcolor(lua_State* L, struct ColorTable* ct) {
lua_newtable(L); //創(chuàng)建一個(gè)新的table, 并將其壓入棧
stack_dump(L);
setfield(L, "r", ct->red);
setfield(L, "g", ct->green);
setfield(L, "b", ct->blue);
int red = getfield(L, -1, "r");
int green = getfield(L, -1, "g");
int blue = getfield(L, -1, "b");
printf("red =%d , green=%d, blue=%d\n", red, green, blue);
lua_setglobal(L, ct->name); //給棧頂變量設(shè)置名字,并把棧頂元素彈出
stack_dump(L);
}
int main() {
lua_State* L = luaL_newstate();
ColorTable colortable[] = {
{"WHITE", MAX_COLOR, MAX_COLOR, MAX_COLOR},
{"RED", MAX_COLOR, 0, 0},
{"GREEN", 0, MAX_COLOR, 0},
};
for (int i = 0; i < 3; i++) {
setcolor(L, &colortable[i]);
}
lua_close(L);
system("pause");
}