Lua脚本和C++交互(一)

现在,越来越多的C++服务器和客户端融入了脚本的支持,尤其在网游领域,脚本语言已经渗透到了方方面面,比如你可以在你的客户端增加一个脚本,这个脚本将会帮你在界面上显示新的数据,亦或帮你完成某些任务,亦或帮你查看别的玩家或者NPC的状态。。。如此等等。

但是我觉得,其实脚本语言与C++的结合,远远比你在游戏中看到的特效要来的迅猛。它可以运用到方方面面的领域,比如你最常见的应用领域。比如,你可以用文本编辑器,写一个脚本语言,然后用你的程序加载一下,就会产生出很绚丽的界面。亦或一两句文本语言,就会让你的程序发送数据给服务器,是不是很酷呢?
本来我想,写一篇关于主流脚本语言Lua和Python的文章,但是感觉这样过于乏味,于是分开来一一介绍,相信对C++了解的你,看过我的文章后会对脚本语言这种东西产生浓厚的兴趣,我想起以前听的一个故事,当年Java的创造者讲课的时候,一开始先拿一个简单的不能简单的小例子,不断的扩展,最后成为一个复杂而完美的程序。今天我也就这样实验一下吧,呵呵。

当然,我本人不敢说对脚本语言了如指掌,只能说略微掌握一些,用过几年,偏颇之处请大家指正。
下面,开始吧,先说LUA!(本文面向初学者)

Lua语言(http://www.lua.org/),想必不少程序员都听过,据我所知,由于《魔兽世界》里面对它的加载,它一下子变成了很多游戏开发者竞相研究的对象,至于这个巴西创造者么,我不过多介绍,大家有兴趣可以谷歌一下。其实网上有很多关于lua的教材和例子,说真的,对于当年的我而言,几乎看不懂,当时很郁闷,感觉Lua复杂的要命,有些惧怕,后来沉下心来一点点研究,觉得其实还是蛮简洁的。只是网上的资料或许偏向于某些功能,导致了逻辑和代码的复杂。后来总结,其实学习一种脚本语言,完全可以抱着放松的心态一点点的研究,反而效果会更好。

在讲代码之前,我要说Lua的一些特点,这些特点有利于你在复杂的代码调用中,清晰的掌握中间的来龙去脉。实际上,你能常常用到的lua的API,不过超过10个,再复杂的逻辑。基本上也是这么多API组成的。至于它们是什么,下面的文章会介绍。另外一个重要之重要的概念,就是栈。Lua与别的语言交互以及交换数据,是通过栈完成的。其实简单的解释一下,你可以把栈想象成一个箱子,你要给他数据,就要按顺序一个个的把数据放进去,当然,Lua执行完毕,可能会有结果返回给你,那么Lua还会利用你的箱子,一个个的继续放下去。而你取出返回数据呢,要从箱子顶上取出,如果你想要获得你的输入参数呢?那也很简单,按照顶上返回数据的个数,再按顺序一个个的取出,就行了。不过这里提醒大家,关于栈的位置,永远是相对的,比如-1代表的是当前栈顶,-2代表的是当前栈顶下一个数据的位置。栈是数据交换的地方,一定要有一些栈的概念。

好了,基础的lua语法不在这里讲,百度一下有很多。
先去http://www.lua.org/ 去下载一个最新的Lua代码(现在稳定版是lua-5.1.4)。它的代码是用C写的,所以很容易兼容很多平台。
在linux下,目录src下就有专门的Makefile。很简单,啥都不用做,指定一下位置编译即可。
在windows下,以VS2005为例,建立一个空的静态库工程(最好不使用预编译头,把预编译头的选项勾去掉),然后把src下的所有文件(除了Makefile)一股脑拷到工程中去。然后将这些文件添加到你的工程中,编译,会生成一个*.llib(*是你起的lua库名),行了,建立一个目录lib,把它拷过去,然后再建立一个include的文件夹,把你工程目录下的lua.h,lualib.h,lauxlib.h,拷贝过去。行了,拿着这两个文件夹,你就可以在你的工程里使用lua了。
行了,材料齐了,我们来看看怎么写一个简单的lua程序吧。

(1)lua程序

(2)C++程序(头文件)

extern "C"
{
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
};
class CLuaFn
{
public:
    CLuaFn(void);
    ~CLuaFn(void);

    void Init();    //初始化Lua对象指针参数
    void Close();    //关闭Lua对象指针

    bool LoadLuaFile(const char* pFileName);    //加载指定的Lua文件
    bool CallFileFn(const char* pFunctionName, int nParam1, int nParam2);        //执行指定Lua文件中的函数
private:
    lua_State* m_pState;    //这个是Lua的State对象指针,你可以一个Lua文件对应一个

};

(3)C++程序(.cpp文件)

#include "CLuaFn.h"

CLuaFn::CLuaFn(void){m_pState = NULL;};        //这句干嘛
CLuaFn::~CLuaFn(void){};

//初始化函数
void CLuaFn::Init()
{
    if (NULL == m_pState)
    {
        m_pState = lua_open();    //返回一个lua对象指针
        luaL_openlibs(m_pState);    //加载了所有你可能用到的Lua基本库
    }
}

//关闭Lua对象并释放资源
void CLuaFn::Close()
{
    if(NULL != m_pState)
    {
        lua_close(m_pState);
        m_pState = NULL;
    }
}

bool CLuaFn::LoadLuaFile(const char* pFileName)
{
    int nRet = 0;
    if (NULL == m_pState)
    {
        printf("[CLuaFn::LoadLuaFile]m_pState is NULL./n");
        return false;
    }
    //加载文件的时候尽量放在程序的初始化中
    nRet = luaL_dofile(m_pState, pFileName);
    if (nRet != 0)
    {
        printf("[CLuaFn::LoadLuaFile]luaL_loadfile(%s) is file(%d)(%s)./n", pFileName, nRet, lua_tostring(m_pState, -1));
        return false;
    }
    return true;
}

bool CLuaFn::CallFileFn(const char* pFunctionName, int nParam1, int nParam2)
{
    int nRet = 0;
    if (NULL == m_pState)
    {
        printf("[CLuaFn::CallFileFn]m_pState is NULL./n");
        return false;
    }
    //验证你的Lua函数是否在你当前加载的Lua文件中,并把指针指向这个函数位置
    lua_getglobal(m_pState, pFunctionName);

    // 压栈(顺序:从左到右的参数):第一个参数
    lua_pushnumber(m_pState, nParam1);
    // 压栈:第二个参数
    lua_pushnumber(m_pState, nParam2);
    //执行这个函数,2是输入参数的个数,1是返回值的个数
    nRet = lua_pcall(m_pState, 2, 1, 0);
    if (nRet != 0)
    {
        printf("[CLuaFn::CallFileFn]call function(%s) error(%d)./n", pFunctionName, nRet);
        return false;
    }
    if (lua_isnumber(m_pState, -1) == 1)
    {
        int nSum = lua_tonumber(m_pState, -1);
        printf("[CLuaFn::CallFileFn]Sum = %d./n", nSum);
    }
    return true;
}

(4)C++程序(main文件)

#include "CLuaFn.h"
int main(int argc, char* argv[])
{
    CLuaFn LuaFn;
    LuaFn.Init();
    LuaFn.LoadLuaFile("Sample.lua");
    LuaFn.CallFileFn("func_Add", 11, 12);
    getchar();

    return 0;
}

注:程序中的注释已经很详尽,这里不在对代码进行解释。下载安装lua之后,在vs2010中还要引入相应的库。截图如下:

至此,build成功之后运行,如果出现如下界面则表示成功!

时间: 2024-10-10 16:15:28

Lua脚本和C++交互(一)的相关文章

Lua脚本和C++交互(四)

上一篇中,你已经可以在Lua里面用C++的函数了,那么咱们再增加一点难度,比如,我有一个CTest对象,要作为一个参数,传输给func_Add()执行,怎么办?很简单,如果你对上面的代码仔细阅读,你会发现下面的代码一样简洁.为了支持刚才要说的需求,我们需要把Sample.lua再做一点修改. function func_Add(x, y, f) -- New了一个CTest对象,并进行赋值操作,最后把结果打印在屏幕上 -- local test = CTest:new() -- test:Set

Lua脚本和C++交互(三)

前两篇文章中介绍了C++调用lua.lua栈操作的一些相关知识. 下面说一下Lua的工具.我们下一步要用到其中的一个帮助我们的开发,其实,Lua里面有很多简化开发的工具,你可以去www.sourceforge.net去找一下.它们能够帮助你简化C++对象与Lua对象互转之间的代码.这里说几个有名的,当然可能不全. (lua tinker)如果你的系统在windows下,而且不考虑移植,那么我强烈推荐你去下载一个叫做lua tinker的小工具,整个工具非常简单,一个.h和一个.cpp.直接就可以

Lua脚本和C++交互(二)

上一节讲了一些基本的Lua应用,下面,我要强调一下,Lua的栈的一些概念,因为这个确实很重要,你会经常用到.熟练使用Lua,最重要的就是要时刻知道什么时候栈里面的数据是什么顺序,都是什么.如果你能熟练知道这些,实际你已经是Lua运用的高手了.当你初始化一个栈的时候,它的栈底是1,而栈顶相对位置是-1,说形象一些,你可以把栈想象成一个环,有一个指针标记当前位置,如果-1,就是当前栈顶,如果是-2就是当前栈顶前面一个参数的位置.以此类推.当然,你也可以正序去取,这里要注意,对于Lua的很多API,下

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

话接上篇.成功配置好Qt+Lua+toLua后,我们可以实现在Lua脚本中使用各个Qt的类.直接看代码吧. #include "include/lua.hpp" #include <QWidget> #include <QApplication> #include <QFile> #include <QDebug> static int tolua_new_QWidget(lua_State* pState) { QWidget* wid

Win32下 Qt与Lua交互使用(三):在Lua脚本中connect Qt 对象

话接上文.笔者为了方便使用Lua,自己编写了一个Lua的类.主要代码如下: QLua.h 1 #ifndef QLUA_H 2 #define QLUA_H 3 4 // own 5 #include "include/lua.hpp" 6 7 // qt 8 #include <QObject> 9 #include <QFile> 10 #include <QDebug> 11 12 #include <QWidget> 13 #in

Win32下 Qt与Lua交互使用(四):在Lua脚本中自由执行Qt类中的函数

话接上篇.通过前几篇博客,我们实现在Lua脚本中执行Qt类中函数的方法,以及在Lua脚本中连接Qt对象的信号与槽. 但是,我们也能发现,如果希望在Lua脚本中执行Qt类的函数,就必须绑定一个真正实现功能的函数.如QWidget::show(),需要写一个在栈中取出widget指针,widget调用show()函数的方式.如果希望在Lua中调用大量函数,就需要编写大量的C++实现函数.有没有什么省时省力的好方法呢? 上一篇中我们实现了在Lua脚本中连接信号与槽.我们只是传过去了两个QObject的

第二十三篇:在SOUI中使用LUA脚本开发界面

像写网页一样做客户端界面可能是很多客户端开发的理想. 做好一个可以实现和用户交互的动态网页应该包含两个部分:使用html做网页的布局,使用脚本如vbscript,javascript做用户交互的逻辑.当需求变化时,只需要在服务端把相关代码调整一下,用户即可看到新的内容(界面). 传统的客户端程序开发流程和网页开发可能完全不同. 首先是界面的布局,在老式的界面布局过程中,程序员先在界面上放好各种控件,然后需要自己通过相应的代码来维护界面在不同状态下控件的显示状态及位置.当界面中元素很多时,单纯布局

Lua脚本在C++下的舞步(入门指引)(转)

http://www.cnblogs.com/hmxp8/archive/2011/11/23/2259777.html 转帖来自:http://www.acejoy.com/bbs/viewthread.php?tid=1931&extra=page%3D1 现在,越来越多的C++服务器和客户端融入了脚本的支持,尤其在网游领域,脚本语言已经渗透到了方方面面,比如你可以在你的客户端增加一个脚本,这个脚本将会帮你在界面上显示新的数据,亦或帮你完成某些任务,亦或帮你查看别的玩家或者NPC的状态...

Lua 跟 C++ 的交互

Lua 和 C++ 是这样交互的 乱七八糟的前戏: 1. 到官网下载 Lua 文件  可參考 ->  Lua 下载与配置 2. 设置环境  可參考  ->  VS 配置Lua环境 交互过程有: 1. C++ 訪问 Lua 的变量 2. C++ 调用 Lua 的函数 3. Lua 訪问 C++ 的变量 4. Lua 訪问 C++ 的函数 No code say a j8 C++ 调用 Lua #include <iostream> #include <string> //