lua_tinker学习笔记(1)

来源:互联网 发布:windows ntp服务器软件 编辑:程序博客网 时间:2024/06/06 07:00

     前两个星期跳槽到了一家游戏公司,做游戏一直是我的梦想。现在终于在毕业三年后,正式开始为了自己的梦想而努力。

      由于之前从事的是交通行业,做游戏服务端开发需要的很多技术以前都没怎么接触过,在重新找工之前恶补了一下lua脚本语言。公司这边C++与lua之间的交互用的是lua_tinker来实现的。lua是用C语言写的,lua_tinker也是用C++对lua api的封装。soga..现在终于体会到之前读书的时候为啥总是听说“学会了C/C++语言,以后再接触其他语言比较容易”的含义了。

      废话不多说,直接进入正题。源代码下载地址http://download.csdn.net/detail/linjiang275773682/4070469   高丽棒子代码写的十分简洁,一个.h一个.cpp 5个例子。

 (一)环境配置

      环境配置,首先你需要搭建一个可以用lua的开发环境,这里网上有很多,我就不多说了。然后再将lua_tinker的lua_tinker.h和lua_tinker.cpp添加到你的工程中就可以了。

但是我在配置的时候碰到个问题就是我在google下的lua最新版,在编译的时候总是会报各种错误。无奈直接在公司的svn上拿了目前游戏服务端用的老版本的lua库和头文件,居然就神奇的可以用了。

 (二)lua_tinker代码分析(sample1)

             我们用棒子提供的sample1来对lua_tinker进行一下初体验。

       sample1.lua代码如下:  

       --lua调用C++函数
       result = cpp_func(1, 2)

       print("cpp_func(1,2) = "..result)


       -- C++调用lua函数
       function lua_func(arg1, arg2)
       return arg1 + arg2
       end

       main函数的软代码如下:   

// lua_test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

extern "C"
{
 #include "lua.h"
 #include "lualib.h"
 #include "lauxlib.h"
};

#include "lua_tinker.h"
int cpp_func(int arg1, int arg2)
{
 return arg1 + arg2;
}
int _tmain(int argc, _TCHAR* argv[])
{  
 lua_State* L = lua_open(); //初始化Lua
 luaopen_base(L); //初始化lua基本库
 lua_tinker::def(L, "cpp_func", cpp_func); //在L栈中注册C++函数
 lua_tinker::dofile(L, "sample1.lua"); //加载lua文件
 int result = lua_tinker::call<int>(L, "lua_func", 3, 4); //调用lua中的function lua_func
 printf("lua_func(3,4) = %d\n", result); //返回lua的执行结果
  lua_close(L); //关闭L
    system("PAUSE");
 return 0;
}

 

        

               下面我们用调试模式对lua_tinker的代码进行一下分析

         lua_State* L = lua_open(); //初始化Lua
         luaopen_base(L); //初始化lua基本库

         lua_tinker::def(L, "cpp_func", cpp_func);//在L栈中注册C++函数

         分析:

-------------------------------------------------------------------------------------------------------------------

         template<typename F> //模板函数
         void def(lua_State* L, const char* name, F func)
        {
            lua_pushstring(L, name); //cpp_func压栈
            lua_pushlightuserdata(L, (void*)func); //userdata传入函数指针
            push_functor(L, func); //cpp_func=function  cpp_func ...end
            lua_settable(L, LUA_GLOBALSINDEX); //LUA_GLOBLSINDEX表示在全局表中设置
         }

-------------------------------------------------------------------------------------------------------------------

        lua_tinker::dofile(L, "sample1.lua"); //加载lua文件
        int result = lua_tinker::call<int>(L, "lua_func", 3, 4); //调用lua中的function lua_func

        分析:

--------------------------------------------------------------------------------------------------------------------

 

 template<typename RVal, typename T1, typename T2>//模板函数,棒子模板用的真实牛逼
 RVal call(lua_State* L, const char* name, T1 arg1, T2 arg2) //call(L,luafunc,3,4)
 {
  lua_pushcclosure(L, on_error, 0);
  int errfunc = lua_gettop(L); //错误处理

  lua_pushstring(L, name); //name=luafunc入栈
  lua_gettable(L, LUA_GLOBALSINDEX); //取全局表
  //lua_pushstring,lua_gettable合起来的作用是取lua_func的实际值,即为函数lua_func

  //这两句话组合起来就是lua_getglobal(L,name)  

if(lua_isfunction(L,-1)) //判断 luafunc在sample1.lua中是不是函数
  {
   push(L, arg1); //压栈参数3
   push(L, arg2); //压栈参数4 此时栈到栈顶一次是 luafunc  3  4
   if(lua_pcall(L, 2, 1, errfunc) != 0) //调用samle1.lua函数luafucn 两个参数,一个返回值
   {
    lua_pop(L, 1); //出错的话,清栈
   }
  }
  else
  {
   print_error(L, "lua_tinker::call() attempt to call global `%s' (not a function)", name);
  }

  lua_remove(L, -2); //移除从栈顶数第二个元素
  return pop<RVal>(L); //pop函数中包括了一个lua_tonumber(L,-1)去栈顶结果
 }

 

 ----------------------------------------------------------------------------------------------------------------------

            printf("lua_func(3,4) = %d\n", result);//返回lua的执行结果
            lua_close(L); //关闭L
            system("PAUSE");
            return 0;
            }

结束。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击