设为首页 加入收藏

TOP

LuaWithC++:Lua的基础语法(一)
2017-12-07 14:21:55 】 浏览:396
Tags:LuaWithC Lua 基础 语法

操作流程

1.宿主语言建立Lua解释器(lua状态机)对象。

2.将宿主语言实现的Lua扩展(若有),如函数等,注册到Lua解释器中,供其使用。

3.读入Lua源程序或预先编译后的Lua程序(可以从文件、字符串、网络等任意来源)。

4.执行读入的Lua程序。

Lua与宿主语言的交互

宿主语言通过虚拟机,对Lua脚本中的变量实现增、删、读、写

宿主语言通过虚拟机调用Lua脚本中的函数

宿主语言定义新的数据类型供Lua脚本使用

Lua调用宿主语言编写的函数

基本用法

需要引入的头文件:

extern "C"               //**使用C语言编译**!
{
   #include 
  
            //Lua语言解析器
   #include 
   
     //Lua标准库 #include 
    
      //Lua辅助工具 } 
    
   
  

C++对Lua脚本的调用、解析,无交互

char* code = "for i=0, 5 do print(\'Hello, world!\') end";

void TestCWithLua()
{
    cout << "/*******测试C++调用lua的代码*******/" << endl;
    //1.创建lua解释器对象
    lua_State* s = luaL_newstate(); /*lua_open();*/
    //2.打开所有lua的库文件
    luaL_openlibs(s);
    //3.执行lua字符串代码
    luaL_dostring(s, code);
    //luaL_dofile(s, "LuaSrc\\testcwithlua.lua");
    //4.关闭lua解释器对象
    lua_close(s);
    cout << "/*******结束测试*******/" << endl;
}

上例只实现了对Lua脚本的解析,并没有实现Lua与宿主语言的数据交换和互操作。

和典型的脚本语言引擎相同,Lua虚拟机是一个堆栈机,其一切运算基本都在堆栈上完成,这个堆栈也是Lua API的关键部分,是Lua与宿主语言交换数据的手段。

题外:宿主语言可以用字符串构建任意Lua脚本,实现向Lua程序传递任意数据,就像构建SQL语句一样,也不失是最“笨”的交互方式。

Lua堆栈

这里写图片描述

Lua虚拟机内部有一个堆栈,Lua API提供了对其的操作,不仅有出入栈操作,还可以以数组的形式,通过索引值随机读写栈元素,这是双方交换数据的主要方式。

用宿主语言可以编写供Lua调用的函数,宿主语言需要遵守调用约定,从栈中取得参数,最后也将结果入栈。将宿主函数通过lua_register注册入Lua虚拟机(这一过程实质为向Lua语言添加全局变量),就可以被Lua语言所调用。

宿主语言也可以将Lua函数压栈,再将参数依次压栈,最后使用lua_call,完成对Lua函数的调用。

Lua堆栈索引

这里写图片描述

若Lua虚拟机堆栈里有N个元素,则可以用 1 ~ N 从栈底向上索引,也可以用 -1 ~ -N 从栈顶向下索引,一般后者更加常用。

堆栈的每个元素可以为任意复杂的Lua数据类型,堆栈中没有元素的空位,隐含为包含一个“空”类型数据。

Lua调用C++

testluawithc.lua

a = 13 
b = 5 
q, r = p(a, b) 
print(q, r)
int Divided(lua_State* s)//供Lua使用的函数通用原型
{
    double a = lua_tonumber(s, -2);//取得第一个参数
    double b = lua_tonumber(s, -1);//取得第二个参数
    int ia = static_cast
  
   (a);
    int ib = static_cast
   
    (b); int quot = ia / ib; int rem = ia % ib; lua_pushnumber(s, quot);//将第一个返回值入栈 lua_pushnumber(s, rem);//将第二个返回值入栈 return 2;//返回值为结果个数 } void TestLuaWithC() { cout << "/*******测试lua调用c++的代码*******/" << endl; lua_State* s = luaL_newstate(); luaL_openlibs(s); lua_register(s, "p", Divided); int ret = luaL_dofile(s, "LuaSrc\\testluawithc.lua"); //luaL_dostring(s, "a = 13 b = 5 q, r = p(a, b) print(q, r)"); lua_close(s); cout << "/*******结束测试*******/" << endl; }
   
  

注意:参数的传递,都是通过Lua栈。

由上例可见,可被Lua调用的宿主函数具有统一的原型:int f(lua_State *s),数据传递不通过其参数,而是通过堆栈;整型返回值指明了该函数真正向Lua返回的值的个数,即压栈的结果个数。函数返回后,Lua虚拟机会自动进行清栈工作,不需在函数内部来做。

显然,在Lua中函数可以有不止一个返回值,这在Lua语法中也有体现,可以将函数返回赋值给多个变量。

C++调用lua,lua全局变量和函数调用,有交互

testglobal.lua

show = function(m)
    print('Lua has got: ' ..m)
    return 'It is from Lua'
end
void TestGlobalAndCall()
{
    cout << "/*******测试使用lua全局变量的代码*******/" << endl;
    lua_State* s = luaL_newstate();
    luaL_openlibs(s);
    /*luaL_dostring(s, "show = function(m) \
                                                    print('Lua has got: ' ..m) \     //..字符串连接符
                                                    return 'It is from Lua' \
                                                end");*/
    luaL_dofile(s, "LuaSrc\\testglobal.lua");
    lua_getglobal(s, "show");//获得全局变量show
    lua_pushstring(s, "It is from C");//将字符串压栈
    lua_call(s, 1, 1);//调用lua函数,1个参数,1个返回值
    const char* result = lua_tostring(s, -1);//获取执行后的栈顶元素,即函数执行结果
    cout << "C has got:" << result << endl;
    lua_pop(s, 1);//弹出栈顶元素
    lua_close(s);
    cout << "/*****
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++学习:简单继承初识 下一篇C++中string类实现教程

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目