上一篇我们搭建好了整个的项目环境,现在,我们一起探索一下如何将lua寄宿到C++中。

宿主的实现

我们在LuaWithCPPTest项目下,查看Source.cpp代码如下:

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

 

extern "C"

{

    #include <lua.h>

    #include <lauxlib.h>

    #include <lualib.h>

};

 

void TestLua();

 

int main()

{

    TestLua();

    return 0;

}

 

void TestLua()

{

    lua_State *L = luaL_newstate();

    luaopen_base(L); //

    luaopen_table(L); //

    luaopen_package(L); //

    luaopen_io(L); //

    luaopen_string(L); //

 

    luaL_openlibs(L); //打开以上所有的lib

 

    string str;

 

 

    while (true)

    {

        cout << "请输入Lua代码:" << endl;

        getline(cin, str, '\n');

        if (luaL_loadstring(L, str.c_str())

            || lua_pcall(L, 0, 0, 0) )

        {

            const char * error = lua_tostring(L, -1) ;

            cout << string(error) << endl;

        }

    }

 

    lua_close(L);

}

其中,被extern "C"包起来的是lua的主要函数的声明。在C++中,每个嵌入的lua的生命周期与各自的lua_State对象一一对应。通过luaL_newstate()方法,我们便创建了一个lua解释器。随后的几个luaopen_*方法,都是获取相应lua库的使用权,最后通过luaL_openlibs打开所有的有使用权的lua标准库。一切准备就绪后,我们开始接收输入。

我们通过luaL_loadstring,将所有代码读入lua,并且检查代码是否有语法错误。然后通过lua_pcall,运行代码,将所有的全局变量保存在_G中。通过读取、运行这两步,我们就建立起一个自己的lua解释器了。

将lua作为配置文件

从文件读取lua代码,流程与之前的示例一样,仅是将luaL_loadstring()换成luaL_loadfile()即可。代码如下: 

string str;

while (true)

{

    cout << "输入lua文件路径:" << endl;

    getline(cin, str, '\n');

    if (luaL_loadfile(L, str.c_str())

        || lua_pcall(L, 0, 0, 0) )

    {

        const char * error = lua_tostring(L, -1) ;

        cout << string(error) << endl;

        return;

    }

 

}

现在,我们在lua中定义变量,并且赋值。然后在c++中取值,运算出结果。在lua文件中,内容如下:

在c++中,我们获取a,b两个变量的值,然后相加,算出结果:

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

 

extern "C"

{

 

#include <lua.h>

#include <lauxlib.h>

#include <lualib.h>

};

 

void TestLua();

 

int main()

{

    TestLua();

    return 0;

}

 

void TestLua()

{

    lua_State *L = luaL_newstate();

    luaopen_base(L); //

    luaopen_table(L); //

    luaopen_package(L); //

    luaopen_io(L); //

    luaopen_string(L); //

 

    luaL_openlibs(L); //打开以上所有的lib

 

    string str;

    while (true)

    {

        cout << "输入lua文件路径:" << endl;

        getline(cin, str, '\n');

        if (luaL_loadfile(L, str.c_str())

            || lua_pcall(L, 0, 0, 0) )

        {

            const char * error = lua_tostring(L, -1) ;

            cout << string(error) << endl;

            return;

        }

        else

        {

            break;

        }

 

    }

 

    int a = 0;

    int b = 0;

 

    // 获取a的值

    lua_getglobal(L, "a");

    if (!lua_isnumber(L, -1))

    {

        cout << "-2 error" << lua_isnumber(L, -1) << lua_isnumber(L, -1) << endl;

        return ;

    }

 

    a = lua_tonumber(L, -1);

 

    // 获取b的值

    lua_getglobal(L, "b");

    if (!lua_isnumber(L, -1))

    {

        cout << "-1 error" << endl;

        return ;

    }

    

    b = lua_tonumber(L, -1);

 

    cout << "a = " << a << " b = " << b << endl;

    cout << "a + b = " << a + b << endl;

 

    lua_close(L);

 

}

最后的得到结果如下:

将文件载入lua后,我们通过lua_getglobal()方法,将想要获得的lua值放入栈顶(栈为何物,下篇分析),然后用lua_isnumber(L, –1)来检测栈顶的元素是否是number,若果是,调用lua_tonumber(L,-1)来将栈顶的值传递给c++变量,整个流程为:1、将欲获得的lua值放入栈中;2、检测栈中的值是否ok;3、取出栈中的值。lua有一系列的lua_is*()来检测栈中的值是否是相应的*类型,相应的,也有一系列的lua_to*()来取值:

总结

写这篇的时候,我内心比较纠结,在内容的深度上把握不准,最终我的定位是:这系列只描述两者之间交互的步骤、方式,不深入去描述原理。原因很简单,因为我的水平有限。在自己水平不足的情况下,去描述c++与lua内在的交互原理,会误导人。我目前的大纲是:第一篇搭建环境;第二篇描述C++调用lua的一些数据;第三篇讲解C++与lua之间的栈,主要还是偏重C++代码调用lua代码。第四篇描述lua如何调用c++代码。第五篇介绍工具tolua++。以上。

C++与Lua交互(二)的更多相关文章

  1. C++与Lua交互(四)

    引言 通过前几篇,我们已经对Lua的C API有了一定的了解,如lua_push*.lua_is*.lua_to*等等.用C++调用Lua数据时,我们主要运用lua_getglobal与lua_pus ...

  2. C++与Lua交互(一)

    引言 之前做手游项目时,客户端用lua做脚本,基本所有游戏逻辑都用它完成,玩起来有点不爽,感觉"太重"了.而我又比较偏服务端这边(仅有C++),所以热情不高.最近,加入了一个端游项 ...

  3. C++与Lua交互之配置&交互原理&示例

    |Lua 简介 Lua 是一种轻量小巧的脚本语言,也是号称性能最高的脚本语言,它用C语言编写并以源代码形式开放. 某些程序常常需要修改内容,而修改的内容不仅仅是数据,更要修改很多函数的行为. 而修改函 ...

  4. Cocos 2d-X Lua 游戏添加苹果内购(二) OC和Lua交互代码详解

    这是第二篇 Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程 这是前面的第一篇,详细的说明了怎样添加内购项目以及填写银行信息提交以及沙盒测试员的添加使用以及需要我们注意的东西,结 ...

  5. 教程二 网页和lua交互修改openwrt

    硬件 http://zhan.renren.com/h5/entry/3602888498044209332 GL-iNet 1 首先安装 webserver之lighttpd  ,openwrt自带 ...

  6. Win32下 Qt与Lua交互使用(二):在Lua脚本中使用Qt类

    话接上篇.成功配置好Qt+Lua+toLua后,我们可以实现在Lua脚本中使用各个Qt的类.直接看代码吧. #include "include/lua.hpp" #include ...

  7. 最优雅的C++跟lua交互.

    我先来吐槽一下我们这个项目. 我是做手机游戏的, cocos2dx引擎, lua编码. 这本来是一件很欢快的事情, 因为不用接触C++. C++写久了的人写lua, 就会感觉任督二脉被打通了, 代码写 ...

  8. vs2013如何在C++中调用Lua(二)

    Lua学习笔记 vs2013如何在C++中调用Lua (此为转载教程) 本人试过完全可行 一.准备工作 1.下载Lua源码,地址:http://www.lua.org/download.html(我用 ...

  9. C++与Lua交互(三)

    通过上一篇的热身,我们对C++调用lua变量有了一个认识,现在让我们再深入一点,去探索一下如何调用lua的函数.表. Lua与宿主通讯的关键--栈 lua是个动态脚本语言,它的数据类型如何映射到C++ ...

随机推荐

  1. sqoop的安装与使用

    1.什么是Sqoop Sqoop即 SQL to Hadoop ,是一款方便的在传统型数据库与Hadoop之间进行数据迁移的工具.充分利用MapReduce并行特点以批处理的方式加快传输数据.发展至今 ...

  2. 关于Android与pc通信时中文乱码的分析和解决

    初步实现了Android与pc服务器的通信之后,又碰到了传说中令人头疼不已的中文乱码问题.既然出现了乱码,那么原因自然是协议不通了.我们知道eclipse中默认的编码标准是GBK,而安卓程序开发所默认 ...

  3. 20种常用的DOS命令小结

    先介绍一下通配符的概念. 通配符*和? *表示一个字符串 ?只代表一个字符 注意通配符只能通配文件名或扩展名,不能全都表示.例如我们要查找以字母y开头的所有文件,可以输入以下命令:dir y*.*:如 ...

  4. memcache 存储session

    php使用memcache存储session   http://blog.csdn.net/weilee2009/article/details/7658260

  5. Helpers\Sessions

    Helpers\Sessions The session is a static class, this means it can be used in any controller without ...

  6. Computer skills one can learn within one day

    Computer related technical skills are usually thought as complicated and difficult to understand. It ...

  7. 小白日记28:kali渗透测试之Web渗透-扫描工具-Nikto

    扫描工具-Nikto #WEB渗透 靶机:metasploitable 靶场:DVWA[默认账号/密码:admin/password] #新手先将DVWA的安全性,调到最低,可容易发现漏洞 侦察[减少 ...

  8. c++之函数原型

    函数原型: [作用域] [函数连接规范] 返回值类型 [函数调用规范] 函数名 (类型1[形参1]...); 函数定义: [函数连接规范] 返回值类型 [函数调用规范] 函数名 (形参列表) {... ...

  9. Android(java)学习笔记74:Java线程池

    线程池: 1)程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互.而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池. 2)线程池里的每一 ...

  10. 使用NumberPicker定制自己喜欢的Date&TimePicker

    1.NumberPicker简介: NumberPicker是Android3.0之后引入的一个控件,主要功能是用于选择一组预定义好数字的控件. 该控件主要需要指导一个用于监听当前value变化的li ...