c++ 与 lua的关系
2015-10-16 11:57
513 查看
脚本语言对于c++等语言存在着许多天然的优势,游戏引擎都需要支持脚本语言,cocos2dx 支持lua、js脚本语言进行开发.主要分析lua与coco2dx引擎中c++的关联。
lua作为脚本语言,经常在游戏开发中使用到. lua的源码是由c实现,能够很好的存活在宿主环境中,所以跟c++的交互实现也很简单。
1、环境搭配(visual studio)
下载lua源码,目录中的存在INSTALL文件指导编译。
windows 由lua.lib lua.exe luac.exe 分别为lua的库,lua的解释器,lua编译器 ,
按照INSTALL的要求,将不同项目需求的源文件加入项目中,根据 exe,lib设置输出配置类型。
在项目中需要使用lua,lua.h lualib.h lauxlib.h luaconf.h 以及库文件即可。
2、c++ 调用 lua 脚本
由于lua是由c实现的所以提供了C API来实现对lua脚本的控制、调用.http://www.lua.org/manual/5.1/manual.html(C
API)
c++调用lua的流程:
1、包含lua.h、lualib.h、lauxlib.h头文件,其中定义了Lua提供的基础函数。
2、若使用c++编译器,c++为支持多态会对函数名跟参数进行处理生成中间函数名,c不会生成中间函数名,出现无法找到函数的实现,链接错误。由于lua是c语言实现所以通过extern "C"{}关键字告诉编译器使用c语言的编译链接形式。
3、通过lua_open()创建一个新的Lua环境(5.2需要使用luaL_newstate来创建lua_open已经废了),返回值为lua_State结构体类型变量,由于Lua库没有定义任何全局变量,所有状态都保存在这个结构体中,所以Lua函数的第一个参数都指向这个结构体变量,能够保存lua环境中的状态。
4、使用luaL_openlibs函数,会在该环境下导入所有的lua标准库。
5、我们要运行lua文件中的将lua文件通过luaL_loadfile函数内部调用lua_load 加载 lua chunk到栈顶,并不运行chunk。
6、lua_pcall(L,0,0,0)实例化chunk.
7、通过lua_getglobal(L,"function_name")把值(函数名称、lua变量名)推送到栈顶。
8、函数带有参数,需要使用lua_push开头后面跟类型名称的函数将对应类型push到栈顶。push是从第一个参数开始(先测试常用的类型,以后了解自定义类型,指针类型)。
9、lua_pcall (lua_State *L, int nargs, int nresults, int msgh)执行先前的function_name的函数,nargs就是函数的参数个数,nresults就是返回值的个数。msg0 栈顶显示原始的出错信息。
10、lua_isnumber(L,-1)判断栈顶是否是数字。若执行成功,栈顶就是数据的返回值。第二个参数为栈的索引值,整数1, 2, 3, 4表示从栈底数起,负数-1,-2,-3,-4表示从栈顶数起。
11、获取返回值lua_tonumber(L,-1). -1代表最后返回的值也是最后压入栈中的。需要将值lua_pop(L,1),弹出N个元素从栈中因为返回值为1则第二个参数为1,函数没有返回值不需要执行该操作。
12、lua_close 释放资源
简单例子
extern "C"
{
#include<lua.h>
#include<lualib.h>
#include<lauxlib.h>
}
#pragma comment(lib,"lualib.lib")
#include <iostream>
using namespace std;
int main()
{
lua_State *L = lua_open();
if (NULL == L)
cout << "create lua failed"<<endl;
luaL_openlibs(L);
if (LUA_ERRFILE ==luaL_loadfile(L,"./test.lua"))
cout << "can't open lua file "<< endl;
lua_pcall(L,0,0,0);
lua_getglobal(L,"hello");
lua_pcall(L,0,0,0);
lua_getglobal(L,"add");
lua_pushnumber(L,10);
lua_pushnumber(L,5);
if (lua_pcall(L,2,2,0) !=0)
cout << lua_tostring(L,-1)<<endl;
if (!(lua_isnumber(L,-1)&&lua_isnumber(L,-2))
cout << "error" << endl;
cout << lua_tonumber(L,-1) <<endl;
cout << lua_tonumber(L,-2) <<endl;
lua_pop(L,2);
lua_close(L);
system("pause");
return 0;
}
test.lua
function hello()
print("Hello")
end
function add(x,y)
return x+y,x-y
end
luaL_loadfile 是加载一个chunk到栈顶,当 Lua 预编译一个 chunk 的时候, chunk 作为一个函数,整个函数体也就被预编译了,通过lua_gettop(L) lua_typename(L,lua_type(L,-1))返回值可证明,
Lua 执行了函数定义,这个函数本身就被实例化了,需要调用chunk中的函数(hello,add都在chunk中),先将chunk通过lua_pcall(L,0,0,0)实例化。所以如上代码多了一个函数调用实例化chunk。
上面可知Lua实现了一个虚拟栈,和C/C++交换数据都通过这个虚拟栈进行.lua_state就是这个栈的实现,c++与lua的定义类型不一样,通过显性调用C
API可以用来指明以哪种类型来解析数据。在内存的释放方面还不确定需要,后续查看lua的源码进行了解。。。。。
lua作为脚本语言,经常在游戏开发中使用到. lua的源码是由c实现,能够很好的存活在宿主环境中,所以跟c++的交互实现也很简单。
1、环境搭配(visual studio)
下载lua源码,目录中的存在INSTALL文件指导编译。
windows 由lua.lib lua.exe luac.exe 分别为lua的库,lua的解释器,lua编译器 ,
按照INSTALL的要求,将不同项目需求的源文件加入项目中,根据 exe,lib设置输出配置类型。
在项目中需要使用lua,lua.h lualib.h lauxlib.h luaconf.h 以及库文件即可。
2、c++ 调用 lua 脚本
由于lua是由c实现的所以提供了C API来实现对lua脚本的控制、调用.http://www.lua.org/manual/5.1/manual.html(C
API)
c++调用lua的流程:
1、包含lua.h、lualib.h、lauxlib.h头文件,其中定义了Lua提供的基础函数。
2、若使用c++编译器,c++为支持多态会对函数名跟参数进行处理生成中间函数名,c不会生成中间函数名,出现无法找到函数的实现,链接错误。由于lua是c语言实现所以通过extern "C"{}关键字告诉编译器使用c语言的编译链接形式。
3、通过lua_open()创建一个新的Lua环境(5.2需要使用luaL_newstate来创建lua_open已经废了),返回值为lua_State结构体类型变量,由于Lua库没有定义任何全局变量,所有状态都保存在这个结构体中,所以Lua函数的第一个参数都指向这个结构体变量,能够保存lua环境中的状态。
4、使用luaL_openlibs函数,会在该环境下导入所有的lua标准库。
5、我们要运行lua文件中的将lua文件通过luaL_loadfile函数内部调用lua_load 加载 lua chunk到栈顶,并不运行chunk。
6、lua_pcall(L,0,0,0)实例化chunk.
7、通过lua_getglobal(L,"function_name")把值(函数名称、lua变量名)推送到栈顶。
8、函数带有参数,需要使用lua_push开头后面跟类型名称的函数将对应类型push到栈顶。push是从第一个参数开始(先测试常用的类型,以后了解自定义类型,指针类型)。
9、lua_pcall (lua_State *L, int nargs, int nresults, int msgh)执行先前的function_name的函数,nargs就是函数的参数个数,nresults就是返回值的个数。msg0 栈顶显示原始的出错信息。
10、lua_isnumber(L,-1)判断栈顶是否是数字。若执行成功,栈顶就是数据的返回值。第二个参数为栈的索引值,整数1, 2, 3, 4表示从栈底数起,负数-1,-2,-3,-4表示从栈顶数起。
11、获取返回值lua_tonumber(L,-1). -1代表最后返回的值也是最后压入栈中的。需要将值lua_pop(L,1),弹出N个元素从栈中因为返回值为1则第二个参数为1,函数没有返回值不需要执行该操作。
12、lua_close 释放资源
简单例子
extern "C"
{
#include<lua.h>
#include<lualib.h>
#include<lauxlib.h>
}
#pragma comment(lib,"lualib.lib")
#include <iostream>
using namespace std;
int main()
{
lua_State *L = lua_open();
if (NULL == L)
cout << "create lua failed"<<endl;
luaL_openlibs(L);
if (LUA_ERRFILE ==luaL_loadfile(L,"./test.lua"))
cout << "can't open lua file "<< endl;
lua_pcall(L,0,0,0);
lua_getglobal(L,"hello");
lua_pcall(L,0,0,0);
lua_getglobal(L,"add");
lua_pushnumber(L,10);
lua_pushnumber(L,5);
if (lua_pcall(L,2,2,0) !=0)
cout << lua_tostring(L,-1)<<endl;
if (!(lua_isnumber(L,-1)&&lua_isnumber(L,-2))
cout << "error" << endl;
cout << lua_tonumber(L,-1) <<endl;
cout << lua_tonumber(L,-2) <<endl;
lua_pop(L,2);
lua_close(L);
system("pause");
return 0;
}
test.lua
function hello()
print("Hello")
end
function add(x,y)
return x+y,x-y
end
luaL_loadfile 是加载一个chunk到栈顶,当 Lua 预编译一个 chunk 的时候, chunk 作为一个函数,整个函数体也就被预编译了,通过lua_gettop(L) lua_typename(L,lua_type(L,-1))返回值可证明,
Lua 执行了函数定义,这个函数本身就被实例化了,需要调用chunk中的函数(hello,add都在chunk中),先将chunk通过lua_pcall(L,0,0,0)实例化。所以如上代码多了一个函数调用实例化chunk。
上面可知Lua实现了一个虚拟栈,和C/C++交换数据都通过这个虚拟栈进行.lua_state就是这个栈的实现,c++与lua的定义类型不一样,通过显性调用C
API可以用来指明以哪种类型来解析数据。在内存的释放方面还不确定需要,后续查看lua的源码进行了解。。。。。
相关文章推荐
- casperjs中evaluate() thenEvaluate()的讲解及使用方法
- lua语法学习2
- Lua文件加密
- Lua中string.format转义符的使用
- Lua栈操作详解
- lua 调用 java oc
- Lua 入门学习
- lua调用c函数
- opentesty--luasocket 安装
- ngx lua
- 关于quick里面报SIGSEGV(SEGV_MAPERR) libgame.so lua_gettop错误
- lua中字符串匹配笔记
- lua string库
- c调用lua函数
- 【Lua】lua内存泄漏
- skynet的流程分析一
- Lua String
- lua环境安装 转
- lua学习笔记10:lua简单的命令行
- lua和c交互用到的c api介绍