Lua与C++交互(一)————堆栈

这篇具有很好参考价值的文章主要介绍了Lua与C++交互(一)————堆栈。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Lua与C++交互(一)————堆栈

Lua虚拟机

什么是Lua虚拟机

Lua本身是用C语言实现的,它是跨平台语言,得益于它本身的Lua虚拟机。

虚拟机相对于物理机,借助于操作系统对物理机器(CPU等硬件)的一种模拟、抽象,主要扮演CPU和内存的作用。

虚拟机的主要职责就是:执行字节码中的指令,管理全局状态(global_state)、数据栈(StackValue)和函数调用链状态(CallInfo)

可以理解成,lua虚拟机就是一个独立的空间,它会维护Lua的所有运行。

创建Lua虚拟机

使用C函数,luaL_newstate 来创建。

会创建一个lua_State的结构体,该结构体就代表了一个Lua虚拟机。

一个进程中可以创建多个Lua虚拟机,即多个lua_State结构。

Lua虚拟机中是单线程实现,所以,多个创建的Lua虚拟机之间是相互独立的。

cocos2dx中的创建Lua虚拟机的地方

AppDelegate中

bool AppDelegate::applicationDidFinishLaunching()
{
    ;;....
    // register lua module
    auto engine = LuaEngine::getInstance();
    ;;...
}

这里在调用单例LuaEngine的时候,会创建LuaStack

LuaEngine中

bool LuaEngine::init(void)
{
    _stack = LuaStack::create();
    _stack->retain();
    return true;
}

LuaStack中

bool LuaStack::init(void)
{
    _state = lua_open();
    luaL_openlibs(_state);
    toluafix_open(_state);

    // Register our version of the global "print" function
    const luaL_Reg global_functions [] = {
        {"print", lua_print},
        {"release_print",lua_release_print},
        {nullptr, nullptr}
    };
    ;;....
}

其中成员变量_state的类型就是lua_State结构体,也就是Lua虚拟机。lua_open是函数luaL_newstate的宏定义。

同时可以得知,这里Lua虚拟机只有一个,这也是为什么在cocos2dx中需要严格按照规则来进行C++和Lua调用的原因。

lua_State

lua虚拟机对象,本身是一个结构体。

它是一个lua线程的执行状态,所有的C api都是基于这个结构体的。

struct lua_State
{
	CommonHeader;//#define CommonHeader
	GCObject *next; 
	lu_byte tt; 
	lu_byte marked
	lu_byte status;//虚拟机的错误状态码
	StkId top;//栈顶元素所在位置的下一个位置,也就是栈上第一个空闲的位置
	StkId base;//栈上,当前函数的基址(注意不是函数所在位置)
	global_State* l_G;//全局表,环境章节再说
	CallInfo* ci;//当前函数调用信息
	const Instruction* savedpc;//当前函数的指令位置,指向待取指指令的地址
	StkId stack_last;//栈最后一个位置的下一个位置
	StkId stack;//寄存器数组的起始位置
	CallInfo* end_ci;//函数调用信息数组的最后一个位置的下一个位置
	CallInfo* base_ci;//函数调用信息数组首地址
	int stacksize;//栈的大小
	int size_ci;//函数调用信息数组大小
	unsigned short nCcalls;//内嵌C调用层数
	unsigned short baseCcalls;//唤醒协程时的内嵌C调用层数
	lu_byte hookmask;
	lu_byte allowhook;
	int basehookcount;
	int hookcount;
	lua_Hook hook;
	TValue l_gt;//Global表
	TValue env;//环境表的临时位置
	GCObject* openupval;//open状态的upvalues
	GCObject* gclist;
	struct lua_longjmp* errorJmp;//跳转信息单链表,实现try catch的功能,见函数章节
	ptrdiff_t errfunc;//当前错误处理函数在栈上的索引
};

关于lua_State这里不过多阐述,感兴趣的可以看《lua设计与实现》这本书。

或者看看云风的《lua源码赏析》

或者看看这个博客
https://blog.csdn.net/yuanlin2008/category_1307277.html

Lua全局表

global_State 全局状态机

如果说lua_State是面对外面表现的虚拟机对象,那么global_State才是背后真正的大佬,该结构体不对外开放,即无法用Lua公开的API获取到它的指针、句柄或引用。

它里面有对主线程(lua_State实例)的引用、有全局字符串表、有内存管理函数、有GC需要的相关信息以及一切Lua在工作时需要的工作内存等等

想要深入了解,同样可以查看《lua设计与实现》这本书。

Lua堆栈

Lua的堆栈是Lua和C++交互的基础,也就是说C++和Lua之间的数据类型交互都是通过这个虚拟栈进行完成的。

不管是C++需要获取Lua的数据还是需要传递数据给Lua,都需要先将这个数据压入栈中。

Lua与C++交互(一)————堆栈,cocos2dx学习之路,lua,c++,cocos2d

从索引来说,分为正向和逆向索引。其中-1永远表示栈顶,1永远表示栈底。

入栈操作

涉及到一些Lua入栈的函数(常用)。

函数 原型 说明
lua_pushnumber void lua_pushnumber (lua_State *L, lua_Number n) 将数值类型n 压入栈中
lua_pushnil void lua_pushnil (lua_State *L) 将nil压入栈中
lua_pushboolean void lua_pushboolean (lua_State *L, int b); 将布尔类型压入栈中
lua_pushfstring const char *lua_pushfstring (lua_State *L, const char *fmt, …) 把一个格式化过的字符串压入堆栈,然后返回这个字符串的指针
lua_pushinteger void lua_pushinteger (lua_State *L, lua_Integer n) 将一个整型数字n压入栈中
lua_pushlstring void lua_pushlstring (lua_State *L, const char *s, size_t len) 把指针 s 指向的长度为 len 的字符串压栈
lua_pushstring void lua_pushstring (lua_State *L, const char *s) 把指针 s 指向的以零结尾的字符串压栈
lua_pushthread int lua_pushthread (lua_State *L) 把 L 中提供的线程压栈。 如果这个线程是当前状态机的主线程的话返回 1
lua_pushvalue void lua_pushvalue (lua_State *L, int index) 把堆栈上给定有效处索引处的元素作一个拷贝压栈
lua_pushlightuserdata void lua_pushlightuserdata (lua_State *L, void *p) 把一个 light userdata 压栈。 userdata 在 Lua 中表示一个 C 值。light userdata 表示一个指针。它是一个像数字一样的值:你不需要专门创建它,它也没有独立的 metatable ,而且也不会被收集(因为从来不需要创建)。只要表示的 C 地址相同,两个 light userdata 就相等
lua_pushcfunction void lua_pushcfunction (lua_State *L, lua_CFunction f) 将一个 C 函数压入堆栈。 这个函数接收一个 C 函数指针,并将一个类型为 function 的 Lua 值 压入堆栈。当这个栈顶的值被调用时,将触发对应的 C 函数

具体可以查看

https://www.w3cschool.cn/doc_lua_5_1/lua_5_1-index.html#lua_pushnumber

取值和出栈

与之对应的取值为:

lua_to*(lua_State * L,栈中位置)取值

对应的出栈为:

lua_pop(lua_State * L,出栈个数)出栈

举例

myName = “beauty girl”

Lua与C++交互(一)————堆栈,cocos2dx学习之路,lua,c++,cocos2d文章来源地址https://www.toymoban.com/news/detail-671243.html

  1. C++想要获取myName的值,根据规则,它需要把myName压入栈中,这样lua就能看到;
  2. lua从堆栈中获取myName的值,此时栈顶为空;
  3. lua拿着myName去全局表中查找与之对应的字符串;
  4. 全局表找到,并返回"beauty girl";
  5. lua把"beauty girl"压入栈中;
  6. C++从栈中获取"beauty girl"

到了这里,关于Lua与C++交互(一)————堆栈的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《入门级-Cocos2dx4.0 塔防游戏开发》---第六课:欢迎界面开发(四、自定义精灵)

    目录  一、开发环境 二、开发内容 2. 1 新建自定义精灵 2.2 在welcome中创建新的menu 2.3 消息绑定以及消息响应 三、演示效果 四、知识点 4.1 内部消息响应 4.2 字体精灵说明 4.3 CC_SYNTHESIZE宏 操作系统:UOS1060专业版本。 cocos2dx:版本4.0 环境搭建教程:统信UOS下配置安装cocos2dx开发

    2024年02月11日
    浏览(42)
  • cocos2d-x C++与Lua交互

    Cocos版本: 3.10 Lua版本: 5.1.4 环境: window Visual Studio 2013 Lua 作为一种脚本语言, 它的运行需要有 宿主 的存在,通过 Lua虚拟栈 进行数据交互。 它的底层实现是 C 语言,C语言封装了很多的API接口,使得C/C++与Lua之间可以很方便的通信交互。 Lua的官网: https://www.lua.org/ 在coc

    2024年02月08日
    浏览(46)
  • cocos2d-x Android原生平台与Lua交互

    版本: cocos2d-x 语言: C++/Java/Lua cocos2d-x原生平台Android 接入第三方SDK, 需要了解 LuaJavaBridge 的使用。 它封装了用于 Java 和 Lua 的相互调用, 其调用通过 C++ 为中介,简要的流程: Lua调用Java: Lua - C++ - Java Java调用Lua: Java - C++ - Lua 以此方式来实现数据的交互, 接下来我们分别说下

    2024年02月08日
    浏览(49)
  • Lua与C++交互(一)————堆栈

    什么是Lua虚拟机 Lua本身是用C语言实现的,它是跨平台语言,得益于它本身的Lua虚拟机。 虚拟机相对于物理机,借助于操作系统对物理机器(CPU等硬件)的一种模拟、抽象,主要扮演CPU和内存的作用。 虚拟机的主要职责就是:执行字节码中的指令,管理全局状态(global_stat

    2024年02月11日
    浏览(42)
  • Pygame和Cocos2d

    Pygame和Cocos2d都是 Python 中常用的游戏引擎,但它们的设计目标、特点和使用场景略有不同。 Pygame与Cocos2d,目前是使用人数最多的两个Python游戏库。根据某知名产品点评网站的数据显示,Cocos2d排名第一,Pygame排名第二。 Pygame是一种基于SDL(Simple DirectMedia Layer)的Python库,主要

    2024年01月21日
    浏览(47)
  • cocos2D插件转3D插件

    cocos2D插件转3D插件

    2024年02月16日
    浏览(48)
  • # Lua与C++交互(二)———— 交互

    基础调用 再来温习一下 myName = “beauty girl” C++想要获取myName的值,根据规则,它需要把myName压入栈中,这样lua就能看到; lua从堆栈中获取myName的值,此时栈顶为空; lua拿着myName去全局表中查找与之对应的字符串; 全局表找到,并返回\\\"beauty girl\\\"; lua把\\\"beauty girl\\\"压入栈中;

    2024年02月11日
    浏览(37)
  • Cocos2d-x实现文字颜色渐变

    更改CCLabel文件的updateColor()函数中的顶点颜色即可,代码如下: 效果图:  

    2024年02月12日
    浏览(44)
  • Lua与C++交互

    1、lua和c++交互机制是基于一个虚拟栈,C++和lua之间的所有数据交互都通过这个虚拟栈来完成,无论何时C++想从lua中调用一个值,被请求的值将会被压入栈,C++想要传递一个值给Lua,首选将整个值压栈,然后就可以在Lua中调用。 2、lua中提供正向和反向索引,区别在于证书永远

    2024年02月08日
    浏览(39)
  • 使用“Cocos引擎”创建的cpp工程如何在VS中调试Cocos2d-x源码

    前段时间Cocos2d-x更新了一个Cocos引擎,这是一个集合源码,IDE,Studio这一家老小的整合包,我们可以使用这个Cocos引擎来创建我们的项目。 在Cocos2d-x被整合到Cocos引擎之前,我们可以不那么方便地在我们创建的工程里调试Cocos2d-x的代码,当我们使用了整合后的Cocos引擎,调试

    2024年02月12日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包