理解Lua和C++交互原理,首先要理解堆栈和全局表
堆栈
Lua和C/C++语言交互的主要方法是一个无处不在的虚拟栈,栈的特点是先进后出。
1.堆栈索引的方式可是是正数也可以是负数。
2.正数索引1永远表示栈底,负数索引-1永远表示栈顶。
3.在Lua中,Lua堆栈就是一个struct.
入栈的数据类型有数值, 字符串, 表等, 但是最后都是统一用TValue这种数据结构来保存。
全局表
Lua的全局表是一个map哈希表结构,比如Lua有一个变量:
key = “value”
全局表中就会存放key和value的对应关系,然后通过key在全局表中查找到world
交互原理
1.C++想要获取Lua中的key对应字符串的值,首先把key放到堆栈(栈顶),方便Lua看到。
2.Lua从堆栈(栈顶)获取到key的值,此时栈顶为空。
3.Lua去全局表中查找key对应的字符串
4.全局表返回对应的字符串value
5.Lua再把value放到堆栈(栈顶)
6.C++从堆栈(栈顶)获取value的值
C++调用Lua
Lua调用C++
1.将C函数作为应用程序的一部分
函数在main方法里注册,使C函数成为全局函数,供Lua调用。
2.将C函数作为Lua的模块
将C函数注册后封装到一个模块中,以库的方式调用,比如在windows系统以dll文件存在,使用时在Lua中require进来就行了。
可以发现无论是在c程序中创建一个lua环境来执行lua代码,还是导出C模块供lua程序使用,都需要手动将C函数注册到lua环境中;另外,C 函数参数和返回值都需要手动操作栈。这个效率是很慢的,最好的办法就是像写普通 C代码一样,然后将 C程序导出成 lua 可以直接调用的代码,tolua 就是干这个事。
进阶(tolua)
tolua是一个工具,负责从包文件(.pkg)生成.c文件或者.cpp文件,这个.c/cpp源文件导出提供Lua调用的源码,并参与工程编译。
在windows系统tolua有以下几个文件
tolua.exe 用于将.pkg生成.cpp文件
tolua.dll
tolua.lib
tolua.h
tolua使用步骤
1.正常编写C++代码,然后编译对应的.pkg文件,pkg文件基本语法与.h保持一致,
2.使用 tolua.exe 从 package 文件生成相应的 c/c++ 源文件。在 tolua.exe 所有目录打开命令行,然后输入 tolua -n [mylib] -o [test.cpp] test.pkg。-n 参数指明这个文件所在的包,如果不写的话就默认跟文件名一样,-o 指明生成的源文件名,这个参数是必须的,最后就是源 package 文件
3.将tolua生成的.cpp源文件参与工程项目编译,在创建lua环境之后调用源文件导出的方法tolua_mylib_open.之后lua就可以调用.pkg里面声明的C++方法。