上一篇我们搭建好了整个的项目环境,现在,我们一起探索一下如何将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++。以上。

最新文章

  1. Java线程:创建与启动
  2. js-JavaScript高级程序设计学习笔记5
  3. 一个WPF控件 诡异的MouseEvent 。
  4. 给定一个整数N,找出一个比N大且最接近N,但二进制权值与该整数相同 的数
  5. c语言mysql api
  6. 【原创】Spring MVC项目搭建(使用Java配置)
  7. KoaHub平台基于Node.js开发的Koa的get/set session插件代码详情
  8. SSE 系列内置函数中的 shuffle 函数
  9. bug 修复:上传库存时前端回发file_name参数丢失;
  10. Android智能手机上的音频浅析
  11. WSUS补丁下载速度慢解决办法
  12. Selenium中三种等待的使用方式---规避网络延迟、代码不稳定问题
  13. cpu资源长期使用率过高导致系统内核锁问题
  14. 利用Hackrf One进行GPS定位欺骗制作超级跑马机
  15. JFinal WEB MVC和Struts简要对比
  16. maven错误The JAVA_HOME environment variable is not defined correctly
  17. 22-[jQuery]-选择器, js jQuery对象转换
  18. 【转】利用telnet来进行调试Skynet
  19. 得到不知道维度的string数组的维度
  20. ggplot饼图

热门文章

  1. C/C++学习站点资源
  2. 搭建Nginx图片服务器
  3. 解决PowerDesigner 反向工程没有注释(备注)
  4. QT断点续传
  5. java 开源缓存框架--转载
  6. 小白日记31:kali渗透测试之Web渗透-扫描工具-Arachni
  7. Ubuntu中useradd和adduser的区别
  8. Android(java)学习笔记92:泛型高级之通配符
  9. Oracle 经典语法(一)
  10. PL/SQL developer 使用技巧汇总