Lua的栈及基本栈操作

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

理解Lua栈

Lua通过一个“虚拟栈”与C/C++程序进行数据交互,所有的Lua C API都是通过操作这个栈来完成相应的数据通信。


Lua的这个“虚拟栈”解决了C/C++程序与Lua程序通信的两大问题:

  • Lua使用垃圾回收,而C/C++需要手动管理内存。

  • Lua使用动态类型,而C/C++使用的是静态类型。


因 为这个栈在Lua虚拟机内部,当一个Lua的变量放在栈里面的时候,虚拟机可以知道它有没有被宿主程序所使用,从而决定是否采用GC。另外Lua采用结构 体封装了类似“Lua_Value”的类型,让它可以存储任何C的类型。从而在数据交换的时候,任何类型都可以被放入栈的一个slot中。


由于栈是FILO的,所以,当我们在Lua里面操作这个栈的时候,每次操作的都是栈的顶部。而Lua的C API则有更多的控制权,它可以非常灵活地操纵这个栈的任意位置的元素。


基本Lua栈操作

  • 往栈里面压入一个值

1
2
3
4
5
6
7
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_pushunsigned (lua_State *L, lua_Unsigned n);
void lua_pushlstring  (lua_State *L, const char *s, size_t len);
void lua_pushstring   (lua_State *L, const char *s);


  • 查询栈里面的元素

1
int lua_is* (lua_State * L, int index);



  • 获取栈内给定位置的元素值

1
xxx lua_toXXX(lua_State * L, int index);

这里面的xxx可以是nil, boolean, string,integer等等。


  • 其它栈操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//取得栈中元素个数
 int  lua_gettop    (lua_State *L);
//设置栈的大小为一个指定的值,而lua_settop(L,0)会把当前栈清空
//如果指定的index大于之前栈的大小,那么空余的空间会被nil填充
//如果index小于之前的栈中元素个数,则多余的元素会被丢弃
 void lua_settop    (lua_State *L, int index);
//把栈中index所在位置的元素压入栈
 void lua_pushvalue (lua_State *L, int index);
//移除栈中index所在位置的元素
void lua_remove(lua_State *L, int index);
//在栈的顶部的元素移动至index处
void lua_insert(lua_State *L, int index);
//从栈顶弹出一个值,并把它设置到给定的index处
void lua_replace(lua_State *L, int index);
//把fromidx处的元素copy一份插入到toidx,这操作不会修改fromidx处的元素
void lua_copy(lua_State *L, int fromidx, int toidx);



另外,根据《Programming In Lua》一书中的所讲,我们可以定义一个函数stackDump来打印当前栈的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
static void stackDump(lua_State* L){
    cout<<"\nbegin dump lua stack"<<endl;
    int i = 0;
    int top = lua_gettop(L);
    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;
        }
    }
    cout<<"\nend dump lua stack"<<endl;
}


C/C++访问Lua的Table

假设我们的Lua文件中有一个Table为:

1
me = { name = "zilongshanren", age = 27}


我们可以通过以下C代码来访问它的元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//从Lua里面取得me这个table,并压入栈
lua_getglobal(L, "me");
if (!lua_istable(L, -1)) {
    CCLOG("error! me is not a table");
}
//往栈里面压入一个key:name
lua_pushstring(L, "name");
//取得-2位置的table,然后把栈顶元素弹出,取出table[name]的值并压入栈
lua_gettable(L, -2);   
//输出栈顶的name
CCLOG("name = %s", lua_tostring(L, -1));
stackDump(L);
//把栈顶元素弹出去
lua_pop(L, 1);
//压入另一个key:age
lua_pushstring(L, "age");
//取出-2位置的table,把table[age]的值压入栈
lua_gettable(L, -2);
stackDump(L);
CCLOG("age = %td", lua_tointeger(L, -1));


Lua5.1还引入了一个新方法:

1
lua_getfield(L, -1, "age");

它可以取代:

1
2
3
4
 //压入另一个key:age
 lua_pushstring(L, "age");
 //取出-2位置的table,把table[age]的值压入栈
 lua_gettable(L, -2);


下篇文章,我们将介绍Lua如何调用C/C++里面的函数。

7、C++处理Lua中的存在嵌套(循环)的Table 我一直在回避一个事情,那就是对嵌套Table的处理。例如在Lua中有如下定义:luat_Nest= {a=123, b=456, c={1,2,3}}其中,成员C就是嵌套的。在C/C++中如何处理呢?其实,对于这种仅仅嵌套一层的表还是比较容易处理的。下面的代码就可以:代码NestTable.cpp #include static void ReadNestTable(lua 阅读详情

相关推荐

5、C++读取Lua中Table的内容

背景知识首先,我们来简单了解一下lua中的Table。Table是lua中唯一内置的数据结构类型。也就是说,它没有内置list、array、map、set等等数据结构类型。在lua里面那些数据类型都是通过Table来实现的。在lua中的,Table是非常强大和重要的。当我们需要将lua嵌入到应用程序里面的时候,不可避免的需要操作Table。本文就来讨论一下如何在C语言中读取Lua中Table

xxNull的专栏 1263

C/C++代码里面读取Lua的Table

本教程将介绍Lua基本操作,同时还有如何在C/C++代码里面读取Lua的Table。

hanxiaoqiag的专栏 5788

lua学习】5.lua_State

1 背景2 (寄存器数组),虚拟机,全局状态机2.1 定义在lua_State结构体中2.2 global_State 全局状态机2.3 lua_newstate 主虚拟机和全局状态机的创建2.4 lua_close 关闭虚拟机2.5 lua_newthread 新建一个协程,,返回这个新协程2.6 lua_atpanic 设置兜底异常处理函数(用于处理未捕获异常的函数),返回旧的兜底异常处理函数3 上的地址3.1 假索引3.2 根据数字索引获取上的地址4 基本操作API4.1 lua_g.

qq_18138105的博客 4269

c++获取lua中table的数据

首先,我们来简单了解一下lua中的Table。Table是lua中唯一内置的数据结构类型。也就是说,它没有内置list、array、map、set等等数据结构类型。在lua里面那些数据类型都是通过Table来实现的。在lua中的,Table是非常强大和重要的。当我们需要将lua嵌入到应用程序里面的时候,不可避免的需要操作Table。本文就来讨论一下如何在C语言中读取Lua中Table的内容。

大猪的博客 7561

图解lua和C——table传递参数过程

先写测试lua脚本: local mytable = require("mytable") local tb = {"hello", "world"} local element = mytable.get(tb, 1) 这个mytable就是我们用C语言编译的库,给lua调用。 local element = mytable.get(tb, 1) 这个函数lua向c传递了2个参数,第一个参...

斧冰 2452

Lua之·Lua与C/C++交互·Lua CAPI访问操作

Lua是一种轻量级的、高性能的脚本语言,经常被用于游戏开发、嵌入式系统和其他需要灵活、可扩展的脚本功能的应用程序中。Lua是一种解释型语言,它具有简单的语法和动态类型系统,使得它易于学习和使用。它的设计目标是成为一种嵌入式脚本语言,在C/C++程序中作为库使用。这使得Lua非常适用于游戏开发,因为它可以与其他编程语言结合使用,提供灵活的脚本功能。Lua的另一个重要特点是它的高性能。与其他动态语言相比,Lua的执行速度非常快,这得益于它的精简设计和高度优化的虚拟机。

m0_66203017的博客 1944

C++ 与 Lua 数据交互载体——

Github传送门(如果对你有所帮助或喜欢的话,赏个star吧,码字不易,请多多支持)如果觉得本篇博文对你有所启发或是解决了困惑,。公众号搜索 “江澎涌”,更多优质文章会第一时间分享与你。

江澎涌的博客 436

lua学习笔记之

-1|___|4 -2|___|3  -3|___|2 -4|___|1 /*堆结构,从底看,从1开始(右边的数字);从顶看以-1开始(左边的数字)*/ /*: 基本操作 中可存放任意类型的数据,lua_push*函数将指定类型的元素入lua_is*判断顶元素的类型,lua_to*获取顶元素,lua_pop将顶元素退lua_settop指定新的顶位置*/

生活不侥幸,缜密务实待人处事 1445

详解关于Lua介绍以及实例

关于Lua介绍以及实例是本文要介绍的内容,主要是lua中如何使用,具体内容的实现来看本文详解。c++中载入lua的代码 #include > //所需要的头文件 extern "C" { #include "include\lua.h" #include "include\lualib.h" #include "include\lauxlib.h" #pragma commen

学习之旅开始啦 1053

Lua和C++交互 学习记录之二:操作

主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:《Lua 5.3 参考手册》中文版译者 云风 制作 Kavcc vs2013+lua-5.3.3 1.理解 ①C++通过lua虚拟机中的lua进行交互。(相当于一个中间层) ②C++自己管理内存;lua自动垃圾回收;虚拟机知道在里的数据是否有被外部宿主程序使用,从而决定是否进行GC...

weixin_33859844的博客 135

Lua

<br />1. 理解lua到底是什么?<br />    lua类似于以下的定义, 它是在创建lua_State的时候创建的:<br />             TValue stack[max_stack_len]  // 欲知内情可以查 lstate.c 的stack_init函数<br />    存入的数据类型包括数值, 字符串, 指针, talbe, 闭包等, 下面是一个的例子:<br />          <br />   执行下面的代码就可以让你的lua上呈现图中的情况<b

zxs421819166的专栏 6795

lua和c++的交互通过解释

print(package.path) package.path = package.path .. ";E:\\OGL5\\c++calllua\\luascript\\?.lua;" print("hello") print(package.path) require 'person' c = add(1,4) print(c) myName = "beauty girl" helloTable = {name="xiaoming", age=12} C++访问lua的table lua_S.

小孔明的专栏 483

理解LUA

理解Lua Lua通过一个“虚拟”与C/C++程序进行数据交互,所有的Lua C API都是通过操作这个来完成相应的数据通信。 Lua的这个“虚拟”解决了C/C++程序与Lua程序通信的两大问题: Lua使用垃圾回收,而C/C++需要手动管理内存。 Lua使用动态类型,而C/C++使用的是静态类型。 因 为这个Lua虚拟

tinyfar的博客 407

Lua 和 C 交互中虚拟操作

Lua 和 C 交互中虚拟操作   /* int lua_pcall(lua_State *L, int nargs, int nresults, int msgh) * 以保护模式调用具有"nargs"个参数,"nresults"个返回值得函数函数在第一个参数的前一个位置。 * 保护模式指的是当调用出错时不会报错,而是返回一个错误码同时将错误信息入。 * 当调用成功时,函数返回0...

weixin_33724046的博客 213

lua--从小白开始(3)

lua笔记

shinhwalin 4148

LuaLua与C交互

上一篇文章简单介绍了在Lua中如何调用C,其中的原理还是需要稍微深究一下。 文章参考自:Lua和C交互的简易教程(HansChen的博客) C/C++与Lua交互的基础源于虚拟。在Lua中,Lua就是一个struct,堆索引的方式可是是正数也可以是负数,区别是:正数索引1永远表示底,负数索引-1永远表示顶 一个简单的例子: #include #includ

mick_seu的博客 2021

lua与CAPI概述

1.  1.1 说明 lua与C语言操作都是通过来进行的。这个是抽象的中每一个元素都能保存任何类型的LUA值。  要获得一个lua中的一个值时(例如一个全局变量),只要调用一个Lua的Api函数Lua就会将指定的值中。  要将一个值传入Lua时,需要先将这个值,然后再调用Lua Api,Lua就会获取值并将此值从中弹出。  几乎所有的lua api都会使

有情怀的梦想家 792

lua 枚举 4

// void lua_pushnil(lua_State* L); --nil值 // void lua_pushboolean(lua_State* L, int b); --布尔值 // void lua_pushnumber(lua_State* L, lua_Number n); --浮点数 // void lua_pushinteger(lua_State* L, lua_Integ

Safedebug的博客 1140
上一篇: 从lua调用C函数
下一篇: C++和Lua相互传递数据
mydriverc2
博客等级 码龄15年 355粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值