• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++与Lua交互(二)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

现在,我们一起探索一下如何将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++。以上。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#中httpclient的使用发布时间:2022-07-13
下一篇:
ListBox控件怎样删除选择的多个Item(c#)发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap