zoukankan      html  css  js  c++  java
  • C++与Lua交互(二)

    上一篇我们搭建好了整个的项目环境,现在,我们一起探索一下如何将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, '
    ');
            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标准库。一切准备就绪后,我们开始接收输入。

    image

    image

    image

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

    将lua作为配置文件

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

    string str;
    while (true)
    {
        cout << "输入lua文件路径:" << endl;
        getline(cin, str, '
    ');
        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;
        }
     
    }

    image

    image

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

    image

    在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, '
    ');
            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);
     
    }

    最后的得到结果如下:

    image

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

    image

    总结

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

  • 相关阅读:
    Atitit.随时间变色特效 ---包厢管理系统的规划
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit.执行cli cmd的原理与调试
  • 原文地址:https://www.cnblogs.com/cdh49/p/3581219.html
Copyright © 2011-2022 走看看