精华内容
下载资源
问答
  • LuaTinker

    千次阅读 2011-02-10 17:50:00
    LuaTinker

     

    LuaTinker的作者是Kwon-il Lee韩国人写的,最新的版本是0.2.C,这个C++ wrapper For Lua能够方便和

    快捷与C/C++通信,LuaTinker参考了luabind和luaplus的特征写的,虽然没有bindlua和luaplus这本强大

    和提供很多功能,LuaTinker的实现只有两个文件,但是LuaTinker提供的基本能够满足大部的要求,用户

    还可以对它进一步的扩充,而且用于游戏上特为方便,以下是LuaTinker使用C++结构和类的例子:

    // 一个基类
    struct base
    {
     base() {}

     const char* is_base(){ return "this is base"; }
    };

    // 一个测试类
    class test : public base
    {
    public:
     test(int val) : _test(val) {}
     ~test() {}

     const char* is_test(){ return "this is test"; }

     void ret_void() {}
     int ret_int()   { return _test;   }
     int ret_mul(int m) const { return _test * m;  }
     A get()    { return A(_test);  }
     void set(A a)   { _test = a.value;  }
     int _test;
    };

    int main()
    {
     // 注册base类型到LUA
     lua_tinker::class_<base>("base")
      .def("is_base", &base::is_base)
      ;
     
     // 注册test类型到LUA,注册test的成员函数和成员变量
     lua_tinker::class_<test>("test")
      .inh<base>() // 注册继承类
      .def(lua_tinker::constructor<int>()) //注册构造函数
      .def("is_test", &test::is_test)           // 注册成员函数
      .def("ret_void", &test::ret_void)
      .def("ret_int", &test::ret_int)
      .def("ret_mul", &test::ret_mul)
      .def("get", &test::get)
      .def("set", &test::set)
      .def_readwrite("_test", &test::_test) // 注册成员变量
      ;

     test g_test(11);
     
     lua_tinker::decl("g_test", &g_test);
     
    }

    // Lua脚本
    temp = test(4)  创建一个test类
    print(temp._test) 打印test的_test成员

    print(g_test)     
    print(g_test._test) 打印g_test的成员变量_test
    print(g_test:is_test()) 输出信息  
    print(g_test:ret_int()) 返回g_test的成员变量_test

    这么几句就能够方便的使用C/C++定义的结构或类,下一篇将会介绍其他的用法.
    介绍完用法之后会从结构上分析lua_tinker的结构和设计.

    // lua_tinker.h
    //
    // LuaTinker - Simple and light C++ wrapper for Lua.
    //
    // Copyright (c) 2005 Kwon-il Lee (zupet@hitel.net)
    // 
    // please check Licence.txt file for licence and legal issues.

    #if !defined(_LUA_TINKER_H_)
    #define _LUA_TINKER_H_

    #include <new>

    namespace lua_tinker
    {
     // debug helpers
     void enum_stack(lua_State *L, int start=0);
     int  _exception(lua_State *L);

     void dofile(const char *filename);
     void dostring(const char* buff);
     void dobuffer(const char* buff, size_t sz);

     void dofile(lua_State *L, const char *filename);
     void dostring(lua_State *L, const char* buff);
     void dobuffer(lua_State *L, const char* buff, size_t sz);

     // basic Object
     struct lua_state
     {
      static void open(lua_State *in)
      { 
       L(in); 
       init_s64(in);
       init_u64(in);
      }

      static lua_State* L(lua_State *in=NULL);
      static void   init_s64(lua_State *L);
      static void   init_u64(lua_State *L);
     };

     // for LuaBind
     struct luabind : lua_state
     {
     };

     struct lua_obj
     {
      lua_obj& operator,(const lua_obj& obj) { return *this; }
     };

     struct module
     {
      module(lua_State *L){}
      void operator[](const lua_obj& obj){}
     };

     struct lua_value
     {
      virtual void to_lua(lua_State *L) = 0;
     };

     // type trait
     template<typename T> struct class_;

     template<bool C, typename A, typename B> 
     struct if_ {};
     template<typename A, typename B> 
     struct if_<true, A, B> { typedef A type; };
     template<typename A, typename B> 
     struct if_<false, A, B> { typedef B type; };

     template<typename A>
     struct is_ptr { static const bool value = false; };
     template<typename A>
     struct is_ptr<A*> { static const bool value = true; };

     template<typename A>
     struct is_ref { static const bool value = false; };
     template<typename A>
     struct is_ref<A&> { static const bool value = true; };

     template<typename A>
     struct remove_const { typedef A type; };
     template<typename A>
     struct remove_const<const A> { typedef A type; };

     template<typename A>
     struct base_type { typedef A type; };
     template<typename A>
     struct base_type<A*> { typedef A type; };
     template<typename A>
     struct base_type<A&> { typedef A type; };

     template<typename A>
     struct class_type { typedef typename remove_const<typename base_type<A>::type>::type type; };
     
     /
     enum { no = 1, yes = 2 }; 
     typedef char (& no_type )[no]; 
     typedef char (& yes_type)[yes];

     struct int_conv_type { int_conv_type(int); };

     no_type int_conv_tester (...); 
     yes_type int_conv_tester (int_conv_type);

     no_type vfnd_ptr_tester (const volatile char *); 
     no_type vfnd_ptr_tester (const volatile short *); 
     no_type vfnd_ptr_tester (const volatile int *); 
     no_type vfnd_ptr_tester (const volatile long *); 
     no_type vfnd_ptr_tester (const volatile double *); 
     no_type vfnd_ptr_tester (const volatile float *); 
     no_type vfnd_ptr_tester (const volatile bool *); 
     yes_type vfnd_ptr_tester (const volatile void *);

     template <typename T> T* add_ptr(T&);

     template <bool C> struct bool_to_yesno { typedef no_type type; }; 
     template <> struct bool_to_yesno<true> { typedef yes_type type; };

     template <typename T> 
     struct is_enum 
     { 
      static T arg; 
      static const bool value = ( (sizeof(int_conv_tester(arg)) == sizeof(yes_type)) && (sizeof(vfnd_ptr_tester(add_ptr(arg))) == sizeof(yes_type)) ); 
     }; 
     /

     // from lua
     template<typename T>
     struct void2val { static T invoke(void* input){ return *(T*)input; } };
     template<typename T>
     struct void2ptr { static T* invoke(void* input){ return (T*)input; } };
     template<typename T>
     struct void2ref { static T& invoke(void* input){ return *(T*)input; } };

     template<typename T>  
     struct void2type
     {
      static T invoke(void* ptr)
      {
       return if_<is_ptr<T>::value
          ,void2ptr<base_type<T>::type>
          ,if_<is_ref<T>::value
           ,void2ref<base_type<T>::type>
           ,void2val<base_type<T>::type>
          >::type
         >::type::invoke(ptr);
      }
     };

     template<typename T>  
     struct user2type { static T invoke(lua_State *L, int index) { return void2type<T>::invoke(lua_touserdata(L, index)); } };

     template<typename T>
     struct lua2enum { static T invoke(lua_State *L, int index) { return (T)(int)lua_tonumber(L, index); } };

     template<typename T>
     struct lua2object
     { 
      static T invoke(lua_State *L, int index) 
      { 
       if(!lua_isuserdata(L,index))
       {
        lua_pushstring(L, "no class at first argument. (forgot ':' expression ?)");
        lua_error(L);
       }
       return void2type<T>::invoke(user2type<user*>::invoke(L,index)->m_p); 
      } 
     };

     template<typename T>
     struct lua2type
     {
      static T invoke(lua_State *L, int index)
      {
       return if_<is_enum<T>::value
          ,lua2enum<T>
          ,lua2object<T> 
         >::type::invoke(L, index);
      }
     };

     struct user
     {
      user(void* p) : m_p(p) {}
      virtual ~user() {}
      void* m_p;
     };

     template<typename T>
     struct val2user : user
     {
      val2user() : user(new T) {}

      template<typename T1>
      val2user(T1 t1) : user(new T(t1)) {}

      template<typename T1, typename T2>
      val2user(T1 t1, T2 t2) : user(new T(t1, t2)) {}

      template<typename T1, typename T2, typename T3>
      val2user(T1 t1, T2 t2, T3 t3) : user(new T(t1, t2, t3)) {}

      ~val2user() { delete ((T*)m_p); }
     };

     template<typename T>
     struct ptr2user : user
     {
      ptr2user(T* t) : user((void*)t) {}
     };

     template<typename T>
     struct ref2user : user
     {
      ref2user(T& t) : user(&t) {}
     };

     // to lua
     template<typename T>
     struct val2lua { static void invoke(lua_State *L, T& input){ new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(input); } };
     template<typename T>
     struct ptr2lua { static void invoke(lua_State *L, T* input){ if(input) new(lua_newuserdata(L, sizeof(ptr2user<T>))) ptr2user<T>(input); else lua_pushnil(L); } };
     template<typename T>
     struct ref2lua { static void invoke(lua_State *L, T& input){ new(lua_newuserdata(L, sizeof(ref2user<T>))) ref2user<T>(input); } };

     template<typename T>
     struct enum2lua { static void invoke(lua_State *L, T val) { lua_pushnumber(L, (int)val); } };

     template<typename T>
     struct object2lua 
     { 
      static void invoke(lua_State *L, T val) 
      { 
       if_<is_ptr<T>::value
        ,ptr2lua<base_type<T>::type>
        ,if_<is_ref<T>::value
         ,ref2lua<base_type<T>::type>
         ,val2lua<base_type<T>::type>
        >::type
       >::type::invoke(L, val);

       class_<class_type<T>::type>::push_meta(L);
       lua_setmetatable(L, -2);
      } 
     };

     template<typename T>
     struct type2lua
     {
      static void invoke(lua_State *L, T val)
      {
       if_<is_enum<T>::value
        ,enum2lua<T>
        ,object2lua<T>
       >::type::invoke(L, val);
      };
     };

     //
     template<typename T>  
     T func_(lua_State *L)
     {
      return user2type<T>::invoke(L, lua_upvalueindex(1));
     }

     // arguments
     struct pop_ 
     {
      template<typename T>  
      static T invoke(lua_State *L, int index)    { return lua2type<T>::invoke(L, index);     }
      template<> 
      static char* invoke(lua_State *L, int index)   { return (char*)lua_tostring(L, index);     }
      template<> 
      static const char* invoke(lua_State *L, int index)  { return (const char*)lua_tostring(L, index);   }
      template<> 
      static char invoke(lua_State *L, int index)    { return (char)lua_tonumber(L, index);     }
      template<> 
      static unsigned char invoke(lua_State *L, int index) { return (unsigned char)lua_tonumber(L, index);   }
      template<> 
      static short invoke(lua_State *L, int index)   { return (short)lua_tonumber(L, index);     }
      template<> 
      static unsigned short invoke(lua_State *L, int index) { return (unsigned short)lua_tonumber(L, index);  }
      template<> 
      static long invoke(lua_State *L, int index)    { return (long)lua_tonumber(L, index);     }
      template<> 
      static unsigned long invoke(lua_State *L, int index) { return (unsigned long)lua_tonumber(L, index);   }
      template<> 
      static int invoke(lua_State *L, int index)    { return (int)lua_tonumber(L, index);     }
      template<> 
      static unsigned int invoke(lua_State *L, int index)  { return (unsigned int)lua_tonumber(L, index);   }
      template<> 
      static float invoke(lua_State *L, int index)   { return (float)lua_tonumber(L, index);     }
      template<> 
      static double invoke(lua_State *L, int index)   { return (double)lua_tonumber(L, index);    }
      template<> 
      static bool invoke(lua_State *L, int index)    { return lua_toboolean(L, index) != 0;     }
      template<> 
      static void invoke(lua_State *L, int index)    { return;            }
      template<> 
      static __int64 invoke(lua_State *L, int index)
      {
       if(lua_isnumber(L,index))
        return (__int64)lua_tonumber(L, index);
       else
        return *(__int64*)lua_touserdata(L, index);
      }
      template<> 
      static unsigned __int64 invoke(lua_State *L, int index)
      {
       if(lua_isnumber(L,index))
        return (unsigned __int64)lua_tonumber(L, index);
       else
        return *(unsigned __int64*)lua_touserdata(L, index);
      }
     };

     // return value
     struct push_
     {
      template<typename T>  
      static void invoke(lua_State *L, T ret)     { type2lua<T>::invoke(L, ret); }
      template<>
      static void invoke(lua_State *L, char ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned char ret)  { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, short ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned short ret) { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, long ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned long ret)  { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, int ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned int ret)  { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, float ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, double ret)   { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, char* ret)    { lua_pushstring(L, ret);  }
      template<>
      static void invoke(lua_State *L, const char* ret)  { lua_pushstring(L, ret);  }
      template<>
      static void invoke(lua_State *L, bool ret)    { lua_pushboolean(L, ret);  }
      template<>
      static void invoke(lua_State *L, lua_value* ret)  { if(ret) ret->to_lua(L); else lua_pushnil(L); }
      template<> 
      static void invoke(lua_State *L, __int64 ret)   
      { 
       *(__int64*)lua_newuserdata(L, sizeof(__int64)) = ret;
       lua_pushstring(L, "__s64");
       lua_gettable(L, LUA_GLOBALSINDEX);
       lua_setmetatable(L, -2);
      }
      template<> 
      static void invoke(lua_State *L, unsigned __int64 ret)
      {
       *(unsigned __int64*)lua_newuserdata(L, sizeof(unsigned __int64)) = ret;
       lua_pushstring(L, "__u64");
       lua_gettable(L, LUA_GLOBALSINDEX);
       lua_setmetatable(L, -2);
      }
     };

     template<typename T>
     struct ret_ { static const int value = 1; };
     template<>
     struct ret_<void> { static const int value = 0; };

     // caller
     template<typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
     struct caller
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3,T4,T5)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4),pop_::invoke<T5>(L,5))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3,T4,T5)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4),pop_::invoke<T5>(L,5)); }
     };

     template<typename T1, typename T2, typename T3, typename T4>
     struct caller<T1,T2,T3,T4> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3,T4)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3,T4)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4)); }
     };

     template<typename T1, typename T2, typename T3>
     struct caller<T1,T2,T3> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3)); }
     };

     template<typename T1, typename T2>
     struct caller<T1,T2> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2)); }
     };

     template<typename T1>
     struct caller<T1> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1)>(L)(pop_::invoke<T1>(L,1))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1)>(L)(pop_::invoke<T1>(L,1)); }
     };

     template<>
     struct caller<void> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)()>(L)()); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)()>(L)(); }
     };

     // function
     template<typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void> 
     struct functor
     {
      template<typename RVal>
      static int invoke(lua_State *L) { caller<T1,T2,T3,T4,T5>::invoke<RVal>(L); return ret_<RVal>::value; }
     };

     template<typename RVal> 
     void push_func(lua_State *L, RVal (*func)())
     {
      lua_pushcclosure(L, functor<>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1> 
     void push_func(lua_State *L, RVal (*func)(T1))
     { 
      lua_pushcclosure(L, functor<T1>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1,class T2> 
     void push_func(lua_State *L, RVal (*func)(T1,T2))
     { 
      lua_pushcclosure(L, functor<T1,T2>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1,class T2, typename T3> 
     void push_func(lua_State *L, RVal (*func)(T1,T2,T3))
     { 
      lua_pushcclosure(L, functor<T1,T2,T3>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1,class T2, typename T3, typename T4> 
     void push_func(lua_State *L, RVal (*func)(T1,T2,T3,T4))
     { 
      lua_pushcclosure(L, functor<T1,T2,T3,T4>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1,class T2, typename T3, typename T4, typename T5> 
     void push_func(lua_State *L, RVal (*func)(T1,T2,T3,T4,T5))
     { 
      lua_pushcclosure(L, functor<T1,T2,T3,T4,T5>::invoke<RVal>, 1);
     }

     // member variable
     template<typename T>
     T* this_(lua_State *L) 
     { 
      return pop_::invoke<T*>(L, 1); 
     }

     struct var_base
     {
      virtual void get(lua_State *L) = 0;
      virtual void set(lua_State *L) = 0;
     };

     template<typename T, typename V>
     struct mem_var : var_base
     {
      V T::*_var;
      mem_var(V T::*val) : _var(val) {}
      void get(lua_State *L) { push_::invoke(L, this_<T>(L)->*(_var));  }
      void set(lua_State *L) { this_<T>(L)->*(_var) = pop_::invoke<V>(L, 3); }
     };

     // member function
     template<typename T,class T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
     struct mem_caller
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3,T4,T5)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5),pop_::invoke<T5>(L,6))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3,T4,T5)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5),pop_::invoke<T5>(L,6)); }
     };

     template<typename T, typename T1, typename T2, typename T3, typename T4> 
     struct mem_caller<T,T1,T2,T3,T4>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3,T4)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3,T4)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5)); }
     };

     template<typename T, typename T1, typename T2, typename T3> 
     struct mem_caller<T,T1,T2,T3>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4)); }
     };

     template<typename T, typename T1, typename T2> 
     struct mem_caller<T,T1, T2>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3)); }
     };

     template<typename T, typename T1> 
     struct mem_caller<T,T1>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1)>(L))(pop_::invoke<T1>(L,2))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1)>(L))(pop_::invoke<T1>(L,2)); }
     };

     template<typename T> 
     struct mem_caller<T>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)()>(L))()); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)()>(L))(); }
     };
     
     // 
     template<typename T, typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void> 
     struct mem_functor
     {
      template<typename RVal>
      static int invoke(lua_State *L) { mem_caller<T,T1,T2,T3,T4,T5>::invoke<RVal>(L); return ret_<RVal>::value; }
     };

     template<typename RVal, typename T>
     void push_func(lua_State *L, RVal (T::*func)()) 
     { 
      lua_pushcclosure(L, mem_functor<T>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T>
     void push_func(lua_State *L, RVal (T::*func)() const) 
     { 
      lua_pushcclosure(L, mem_functor<T>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1>
     void push_func(lua_State *L, RVal (T::*func)(T1)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1>
     void push_func(lua_State *L, RVal (T::*func)(T1) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4,T5)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4,T5>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4,T5) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4,T5>::invoke<RVal>, 1); 
     }

     // constructor
     template<typename T1=void, typename T2=void, typename T3=void, typename T4=void>
     struct constructor {};

     template<typename T1, typename T2, typename T3>
     struct constructor<T1,T2,T3>
     {
      template<typename T>
      static void invoke(lua_State *L)
      {
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4));
      }
     };


     template<typename T1, typename T2>
     struct constructor<T1,T2>
     {
      template<typename T>
      static void invoke(lua_State *L)
      {
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3));
      }
     };

     template<typename T1>
     struct constructor<T1>
     {
      template<typename T>
      static void invoke(lua_State *L)
      {
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2));
      }
     };

     template<>
     struct constructor<void>
     { 
      template<typename T>
      static void invoke(lua_State *L) 
      { 
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>();
      } 
     };

     template<typename T>
     struct creator
     {
      template<typename CONSTRUCTOR>
      static int invoke(lua_State *L) 
      { 
       CONSTRUCTOR::invoke<T>(L);
       class_<class_type<T>::type>::push_meta(L);
       lua_setmetatable(L, -2);

       return 1; 
      }
     };

     // destroyer
     template<typename T>
     struct destroyer
     {
      static int invoke(lua_State *L) 
      { 
       ((user*)lua_touserdata(L, 1))->~user();
       return 0;
      }
     };

     // get
     int get_var(lua_State *L);
     int set_var(lua_State *L);

     // Tinker Function
     template<typename F> 
     lua_obj def(const char* name, F func)
     { 
      lua_State *L = lua_state::L();
      lua_pushstring(L, name);
      lua_pushlightuserdata(L, func);
      push_func(L, func);
      lua_settable(L, LUA_GLOBALSINDEX);

      return lua_obj();
     }

     // Tinker Global
     template<typename T>
     lua_obj decl(const char* name, T object)
     {
      lua_State *L = lua_state::L();
      lua_pushstring(L, name);
      push_::invoke(L, object);
      lua_settable(L, LUA_GLOBALSINDEX);

      return lua_obj();
     }

     // Tinker Call
     template<typename RVal>
     RVal call(const char* name)
     {
      lua_State *L = lua_state::L();

      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      if(lua_isfunction(L,-1))
      {
       lua_pcall(L, 0, ret_<RVal>::value, 1);
      }
      else
      {
       lua_pushfstring(L, "lua_tinker : attempt to call global `%s' (not a function)", name);
       _exception(L);
      }

      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }

     template<typename RVal, typename T1>
     RVal call(const char* name, T1 arg)
     {
      lua_State *L = lua_state::L();

      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      push_::invoke(L, arg);
      lua_pcall(L, 1, ret_<RVal>::value, 1);
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }

     template<typename RVal, typename T1, typename T2>
     RVal call(const char* name, T1 arg1, T2 arg2)
     {
      lua_State *L = lua_state::L();

      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      push_::invoke(L, arg1);
      push_::invoke(L, arg2);
      lua_pcall(L, 2, ret_<RVal>::value, 1);
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }

     template<typename RVal, typename T1, typename T2, typename T3>
     RVal call(const char* name, T1 arg1, T2 arg2, T3 arg3)
     {
      lua_State *L = lua_state::L();

      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      push_::invoke(L, arg1);
      push_::invoke(L, arg2);
      push_::invoke(L, arg3);
      lua_pcall(L, 3, ret_<RVal>::value, 1);
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }

     // Tinker Class
     template<typename T>
     struct class_ : lua_obj
     {
      // initialize
      class_(const char* name) 
      : m_L(lua_state::L())
      { 
       _name(name);

       lua_pushstring(m_L, name);
       lua_newtable(m_L);

       lua_pushstring(m_L, "__name");
       lua_pushstring(m_L, name);
       lua_rawset(m_L, -3);

       lua_pushstring(m_L, "__index");
       lua_pushcclosure(m_L, get_var, 0);
       lua_rawset(m_L, -3);

       lua_pushstring(m_L, "__newindex");
       lua_pushcclosure(m_L, set_var, 0);
       lua_rawset(m_L, -3);

       lua_pushstring(m_L, "__gc");
       lua_pushcclosure(m_L, destroyer<T>::invoke, 0);
       lua_rawset(m_L, -3);

       lua_settable(m_L, LUA_GLOBALSINDEX);
      }

      // constructor
      template<typename CONSTRUCTOR>
      class_<T>& def(CONSTRUCTOR)
      {
       class_<class_type<T>::type>::push_meta(m_L);

       lua_newtable(m_L);
       lua_pushstring(m_L, "__call");
       lua_pushcclosure(m_L, creator<T>::invoke<CONSTRUCTOR>, 0);
       lua_rawset(m_L, -3);
       lua_setmetatable(m_L, -2);
       lua_pop(m_L,1);
       return *this; 
      }

      // inheritence
      template<typename P>
      class_<T>& inh()
      {
       class_<class_type<T>::type>::push_meta(m_L);
       lua_pushstring(m_L, "__parent");
       class_<class_type<P>::type>::push_meta(m_L);
       lua_rawset(m_L, -3);
       lua_pop(m_L,1);
       return *this; 
      }

      // functions
      template<typename F>
      class_<T>& def(const char* name, F func) 
      { 
       class_<class_type<T>::type>::push_meta(m_L);

       lua_pushstring(m_L, name);
       new(lua_newuserdata(m_L,sizeof(F))) F(func);
       push_func(m_L, func);
       lua_rawset(m_L, -3);

       lua_pop(m_L,1);
       return *this; 
      }

      // variables
      template<typename BASE, typename VAR>
      class_<T>& def_readwrite(const char* name, VAR BASE::*val) 
      { 
       class_<class_type<T>::type>::push_meta(m_L);

       lua_pushstring(m_L, name);
       new(lua_newuserdata(m_L,sizeof(mem_var<BASE,VAR>))) mem_var<BASE,VAR>(val);
       lua_rawset(m_L, -3);

       lua_pop(m_L,1);
       return *this; 
      }

      // metatable
      static void push_meta(lua_State *L)
      {
       const char* name = _name();
       if(name[0])
       {
        lua_pushstring(L, name);
        lua_gettable(L, LUA_GLOBALSINDEX);
       }
       else
       {
        lua_pushnil(L);
       }
      }

      // global name
      static const char* _name(const char* name = NULL)
      {
       static char temp[256] = "";
       if(name) strcpy(temp, name);
       return temp;
      }

      lua_State* m_L;     
     };

    } // namespace lua_tinker

    #endif //_LUA_TINKER_H_

    // Lua Test.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include "lua_tinker/lua_tinker.h"

    struct A
    {
     A(int v) : value(v) {}
     int value;
    };

    struct base
    {
     base() {}

     const char* is_base(){ return "this is base"; }
    };

    class test : public base
    {
    public:
     test(int val) : _test(val) {}
     ~test() {}

     const char* is_test(){ return "this is test"; }

     void ret_void() {}
     int ret_int()    { return _test;   }
     int ret_mul(int m) const { return _test * m;  }
     A get()      { return A(_test);  }
     void set(A a)    { _test = a.value;  }

     int _test;
    };

    test g_test(11);

    class parent : public lua_tinker::lua_value
    {
    public:
     void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐

     virtual const char* name() { return "parent"; }

     int m_parent;
    };

    class child : public parent
    {
    public:
     void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐

     const char* name() { return "child"; }

     int m_child;
    };

    class grandchild : public child
    {
    public:
     void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐

     const char* name() { return "grandchild"; }

     int m_grandchild;
    };

    lua_tinker::lua_value* GetChild(int n)
    {
     static parent _parent;
     static child _child;
     static grandchild _grandchild;

     if(n == 0)
      return &_parent;
     else if(n == 1)
      return &_child;
     else
      return &_grandchild;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
     lua_State* L = lua_open();

     // init Lua
     luaopen_base(L);
     luaopen_string(L);
     luaopen_table(L);

     lua_settop(L, 0);

     // LuaTinker
     lua_tinker::lua_state::open(L);

     lua_tinker::class_<base>("base")
      .def("is_base", &base::is_base)
      ;

     lua_tinker::class_<test>("test")
      .inh<base>()
      .def(lua_tinker::constructor<int>())
      .def("is_test", &test::is_test)
      .def("ret_void", &test::ret_void)
      .def("ret_int", &test::ret_int)
      .def("ret_mul", &test::ret_mul)
      .def("get", &test::get)
      .def("set", &test::set)
      .def_readwrite("_test", &test::_test)
      ;
     lua_tinker::decl("g_test", &g_test);

     lua_tinker::class_<parent>("parent")
      .def("name", &parent::name)
      .def_readwrite("m_parent", &parent::m_parent)
      ;

     lua_tinker::class_<child>("child")
      .inh<parent>()
      .def_readwrite("m_child", &child::m_child)
      ;

     lua_tinker::class_<grandchild>("grandchild")
      .inh<child>()
      .def_readwrite("m_grandchild", &grandchild::m_grandchild)
      ;

     lua_tinker::def("GetChild", GetChild);


     // lua_tinker 龋免 抛胶飘
     lua_tinker::dofile(L, "test.lua");

     lua_tinker::call<void>("print", "-------------------------- call<>");
     lua_tinker::call<void>("dir", g_test);
     lua_tinker::call<void>("print", "-------------------------- call<> finished");

     char temp[1024];
     while(true)
     {
      printf(">");
      if(stricmp(gets(temp), "quit") == 0)
       break;
      lua_tinker::dostring(L, temp);
     }

     // close Lua
     lua_close(L);

     return 0;
    }

     

    展开全文
  • LuaTinker问题

    2018-05-25 14:59:04
    LuaTinker是一套还不错的C++代码和Lua代码的绑定库,作者是韩国人Kwon-il Lee,作者应该是参考了LuaBind后,为了简化和避免过重而实现的。其官网在http://gpgstudy.com/gpgiki/LuaTinker ,但可惜全部是韩文的,而...

    LuaTinker是一套还不错的C++代码和Lua代码的绑定库,作者是韩国人Kwon-il Lee,作者应该是参考了LuaBind后,为了简化和避免过重而实现的。其官网在http://gpgstudy.com/gpgiki/LuaTinker ,但可惜全部是韩文的,而最新的代码可以在Git上下载,https://github.com/zupet/LuaTinker 。对比LuaBind,LuaPlus这类库,其实现非常非常非常非常非常轻,大约只有1000多行,至少给了你一个机会,去了解和改写部分功能,所以其在国内也有不少群众基础。而且其轻薄的身材也让剖析一下一个脚本粘合层是如何工作成为了可能。

    但另外一方面LuaTinker的bug数量并不在少数。也有不少同学曾经零散的提出来过。这儿只是做个总结,另外感谢fergzhang同学。很多问题都是他帮忙指出的。

    1. BUG(错误)

    第一个问题,int64_t 数据的比较是错误的,完全没有考虑符号位的情况嘛。

    1. static int lt_s64(lua_State *L)  
    2. {  
    3.      //完全没有考虑符号位的情况,居然用memcmp  
    4.     lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(long long)) < 0);  
    5.     return 1;  
    6. }  

     

    第二个问题,在处理类成员的修改函数(__newindex)时,没有考虑要处理父类成员的,而LuaTinker是支持继承的,而且int lua_tinker::meta_get(lua_State *L) (对应__index)也是支持。这应该是作者的一个疏漏。

    int lua_tinker::meta_set(lua_State *L)
    {
        enum_stack(L);
        lua_getmetatable(L, 1);
        lua_pushvalue(L, 2);
        lua_rawget(L, -2);
        enum_stack(L);
    
        if (lua_isuserdata(L, -1))
        {
            user2type<var_base *>::invoke(L, -1)->set(L);
    }
        else if (lua_isnil(L, -1))
    {
        //这儿没有调用invoke_parent(L)处理父类的情况
            lua_pushvalue(L, 2);
            lua_pushvalue(L, 3);
            lua_rawset(L, -4);
        }
        lua_settop(L, 3);
        return 0;
    }

     

    第三个bug,使用I64d这种过时的标签,I64d应该是微软很老很老很老的一个格式化字符串标签,而且完全不具备可移植性。应该改为%lld。

    static int tostring_s64(lua_State *L)
    {
        char temp[64];
        sprintf_s(temp, "%I64d", *(long long*)lua_topointer(L, 1));
        lua_pushstring(L, temp);
        return 1;
    }

     

    第4个bug,var_base基类的析构函数没有写virtual

    struct var_base
    {
        //原来的析构函数没有写virtual
        virtual ~var_base() {};
        virtual void get(lua_State *L) = 0;
        virtual void set(lua_State *L) = 0;
    };

     

    第5个bug,table的3个构造函数中有一个没有增加引用计数,这个bug在网上很多同学都指出过。

    lua_tinker::table::table(lua_State* L, const char* name)
    {
        lua_pushstring(L, name);
        lua_gettable(L, LUA_GLOBALSINDEX);
    
        if(lua_istable(L, -1) == 0)
        {
            lua_pop(L, 1);
    
            lua_newtable(L);
            lua_pushstring(L, name);
            lua_pushvalue(L, -2);
            lua_settable(L, LUA_GLOBALSINDEX);
        }
    
        m_obj = new table_obj(L, lua_gettop(L));
            //原来的代码没有这段,缺少增加引用计数处理
            m_obj->inc_ref();
    }

    , CSDN的ainn_pp也写过这个问题,参考:http://blog.csdn.net/ainn_pp/article/details/2773855

    1. 缺陷

    LuaTinker也有很多缺陷和不足,

    第一个不足,各种函数参数的支持个数参差不齐。LuaTinker的写的时间应该比较早,没有C++ 11的模版变参(Variadic Template)的支持,所以只能用写多个模版函数(类)的方式解决多模板参数问题。但LuaTinker一方面写的参数个数很少,一方面LuaTinker的个个地方支持的参数个数数量完全不统一,3个,4个,5个的都有。其实这部分最好用C++ 11的(Variadic Template)重写。

    第二个缺陷是个硬伤,LuaTinker对Lua 协程的支持,用了一个很费力,但又不讨好的方式。你必须把协程的第一个参数定义为lua_State *L,而且返回值必须是lua_yield(L, 0)。这样的限制,大大限制了使用。

    //第一个参数必须是(lua_State *L
    int TestFunc2(lua_State *L, float a)
    {
    printf("# TestFunc2(L,%f) is invoke.\n", a);
    //返回的地方必须是调用lua_yield
        return lua_yield(L, 0);
    }
    
    class TestClass
    {
    public:
    
        //类函数也一样
        int TestFunc2(lua_State *L, float a)
        {
            printf("# TestClass::TestFunc2(L,%f) is invoke.\n", a);
            return lua_yield(L, 0);
        }
    };

     

    而如果其实在其函数的封装上加以区分,自己在最后调用lua_yield,这就可以避免这个麻烦。这个实现实在让我没有多大胃口。

    第三个地方是,是对引用变量(参数),注册的问题,其实这个也不是LuaTinker的问题,而是C++模版的问题,C++的自动模版函数参数推导是存在一些潜规则的。其中有一个就是左值变换,在《CUJ:高效使用标准库:显式函数模板参数申明与STL》 一文中有比较清晰的解释。如下示例:

    //下面的写法是无法得到引用的,必须显式指定参数。
    //lua_tinker::set(L, "ref_a", ref_a);
    
    //显式声明引用参数
    lua_tinker::set<TestA &>(L, "ref_a", ref_a);

     

    第4个问题就是,模版处理中,对于cv(const volatile)的去除掉处理也并不理想。Lua内部对于外部的class的注册是使用函数class_add,也就是用一个名称关联一个Lua的meta table,在类的后面的使用中,通过class_name<T>::name函数取得类名,但实际中,很多时候T是带有const 或者 volatile的修饰符的。包括,LuaTinker在部分处理中去掉了const,但很多地方又忽略问题,编译器不会认为classA和const class A是一个东东的。所以结果就是有时候无法让你的userdata找到对应的meta table。

    lua_tinker::class_add<TestA>(L, "TestA");
    lua_tinker::class_con<TestA>(L, lua_tinker::constructor<TestA>);
    
    //用模板函数辅助帮忙实现一个方法,可以通过class 找到对应的类名称(注册到LUA的名称),
    template<typename T>
    struct class_name
    {
        // global name
        static const char *name(const char *name = NULL)
        {
            static char temp[256] = "";
            if (name)
            {
                strcpy_s(temp, name);
            }
            return temp;
        }
    };

     

    fergzhang同学,针对LuaTinker的一些bug修正做了一个版本。同时好像支持了5.2的版本,他放在了https://github.com/zfengzhen/lua_tinker_5.2.git

    而我自己针对上面的问题实现了一套LuaTie的库,没有时间,有时间整理出来。内部用C++ 11的特性做了一些改写。

    https://github.com/sailzeng/zcelib/blob/master/src/commlib/zcelib/zce_script_lua_tie.cpp

    https://github.com/sailzeng/zcelib/blob/master/src/commlib/zcelib/zce_script_lua_tie.h

    工程内部是有测试的例子的,但没有整理出来,看起来比较麻烦。等后面整理出来再写一篇介绍的文章把。

    最后,虽然我在挑刺,但还是再次表达一下对 LuaTinker作者Kwon-il Lee的感谢,这套代码帮助我了解了如何绑定脚本以及了解MPL的一些基本知识.而且坦白讲LuaBind是和Boost绑定的,能费力从这些代码中简化出LuaTinker(阅读Boost代码实在谈不上愉快),真的是一件很了不起的事情,LuaTinker的作者可能更明白轻对于代码的好处,Kwon-il Lee在主页上有一段说明其为什么没有支持LuaBind所支持的重载,而我也认为一个优秀的库始终要是简单的。

    展开全文
  • LuaTinker-master

    2014-11-26 10:05:38
    LuaTinker-master 5.1
  • Luatinker 适用于lua5.3的luatinker
  • LuaTinker 使用

    千次阅读 2011-10-10 10:19:55
    LuaTinker的作者是Kwon-il Lee韩国人写的,最新的版本是0.2.C,这个C++ wrapper For Lua能够方便和 快捷与C/C++通信,LuaTinker参考了luabind和luaplus的特征写的,虽然没有bindlua和luaplus这本强大 和
    
    

    LuaTinker的作者是Kwon-il Lee韩国人写的,最新的版本是0.2.C,这个C++ wrapper For Lua能够方便和

    快捷与C/C++通信,LuaTinker参考了luabind和luaplus的特征写的,虽然没有bindlua和luaplus这本强大

    和提供很多功能,LuaTinker的实现只有两个文件,但是LuaTinker提供的基本能够满足大部的要求,用户

    还可以对它进一步的扩充,而且用于游戏上特为方便,以下是LuaTinker使用C++结构和类的例子:

    // 一个基类
    struct base
    {
     base() {}

     const char* is_base(){ return "this is base"; }
    };

    // 一个测试类
    class test : public base
    {
    public:
     test(int val) : _test(val) {}
     ~test() {}

     const char* is_test(){ return "this is test"; }

     void ret_void() {}
     int ret_int()   { return _test;   }
     int ret_mul(int m) const { return _test * m;  }
     A get()    { return A(_test);  }
     void set(A a)   { _test = a.value;  }
     int _test;
    };

    int main()
    {
     // 注册base类型到LUA
     lua_tinker::class_<base>("base")
      .def("is_base", &base::is_base)
      ;
     
     // 注册test类型到LUA,注册test的成员函数和成员变量
     lua_tinker::class_<test>("test")
      .inh<base>() // 注册继承类
      .def(lua_tinker::constructor<int>()) //注册构造函数
      .def("is_test", &test::is_test)           // 注册成员函数
      .def("ret_void", &test::ret_void)
      .def("ret_int", &test::ret_int)
      .def("ret_mul", &test::ret_mul)
      .def("get", &test::get)
      .def("set", &test::set)
      .def_readwrite("_test", &test::_test) // 注册成员变量
      ;

     test g_test(11);
     
     lua_tinker::decl("g_test", &g_test);
     
    }

    // Lua脚本
    temp = test(4)  创建一个test类
    print(temp._test) 打印test的_test成员

    print(g_test)     
    print(g_test._test) 打印g_test的成员变量_test
    print(g_test:is_test()) 输出信息  
    print(g_test:ret_int()) 返回g_test的成员变量_test

    这么几句就能够方便的使用C/C++定义的结构或类,下一篇将会介绍其他的用法.
    介绍完用法之后会从结构上分析lua_tinker的结构和设计.

     

     

    // lua_tinker.h
    //
    // LuaTinker - Simple and light C++ wrapper for Lua.
    //
    // Copyright (c) 2005 Kwon-il Lee (zupet@hitel.net)
    // 
    // please check Licence.txt file for licence and legal issues.

    #if !defined(_LUA_TINKER_H_)
    #define _LUA_TINKER_H_

    #include <new>

    namespace lua_tinker
    {
     // debug helpers
     void enum_stack(lua_State *L, int start=0);
     int  _exception(lua_State *L);

     void dofile(const char *filename);
     void dostring(const char* buff);
     void dobuffer(const char* buff, size_t sz);

     void dofile(lua_State *L, const char *filename);
     void dostring(lua_State *L, const char* buff);
     void dobuffer(lua_State *L, const char* buff, size_t sz);

     // basic Object
     struct lua_state
     {
      static void open(lua_State *in)
      { 
       L(in); 
       init_s64(in);
       init_u64(in);
      }

      static lua_State* L(lua_State *in=NULL);
      static void   init_s64(lua_State *L);
      static void   init_u64(lua_State *L);
     };

     // for LuaBind
     struct luabind : lua_state
     {
     };

     struct lua_obj
     {
      lua_obj& operator,(const lua_obj& obj) { return *this; }
     };

     struct module
     {
      module(lua_State *L){}
      void operator[](const lua_obj& obj){}
     };

     struct lua_value
     {
      virtual void to_lua(lua_State *L) = 0;
     };

     // type trait
     template<typename T> struct class_;

     template<bool C, typename A, typename B> 
     struct if_ {};
     template<typename A, typename B> 
     struct if_<true, A, B> { typedef A type; };
     template<typename A, typename B> 
     struct if_<false, A, B> { typedef B type; };

     template<typename A>
     struct is_ptr { static const bool value = false; };
     template<typename A>
     struct is_ptr<A*> { static const bool value = true; };

     template<typename A>
     struct is_ref { static const bool value = false; };
     template<typename A>
     struct is_ref<A&> { static const bool value = true; };

     template<typename A>
     struct remove_const { typedef A type; };
     template<typename A>
     struct remove_const<const A> { typedef A type; };

     template<typename A>
     struct base_type { typedef A type; };
     template<typename A>
     struct base_type<A*> { typedef A type; };
     template<typename A>
     struct base_type<A&> { typedef A type; };

     template<typename A>
     struct class_type { typedef typename remove_const<typename base_type<A>::type>::type type; };
     
     /
     enum { no = 1, yes = 2 }; 
     typedef char (& no_type )[no]; 
     typedef char (& yes_type)[yes];

     struct int_conv_type { int_conv_type(int); };

     no_type int_conv_tester (...); 
     yes_type int_conv_tester (int_conv_type);

     no_type vfnd_ptr_tester (const volatile char *); 
     no_type vfnd_ptr_tester (const volatile short *); 
     no_type vfnd_ptr_tester (const volatile int *); 
     no_type vfnd_ptr_tester (const volatile long *); 
     no_type vfnd_ptr_tester (const volatile double *); 
     no_type vfnd_ptr_tester (const volatile float *); 
     no_type vfnd_ptr_tester (const volatile bool *); 
     yes_type vfnd_ptr_tester (const volatile void *);

     template <typename T> T* add_ptr(T&);

     template <bool C> struct bool_to_yesno { typedef no_type type; }; 
     template <> struct bool_to_yesno<true> { typedef yes_type type; };

     template <typename T> 
     struct is_enum 
     { 
      static T arg; 
      static const bool value = ( (sizeof(int_conv_tester(arg)) == sizeof(yes_type)) && (sizeof(vfnd_ptr_tester(add_ptr(arg))) == sizeof(yes_type)) ); 
     }; 
     /

     // from lua
     template<typename T>
     struct void2val { static T invoke(void* input){ return *(T*)input; } };
     template<typename T>
     struct void2ptr { static T* invoke(void* input){ return (T*)input; } };
     template<typename T>
     struct void2ref { static T& invoke(void* input){ return *(T*)input; } };

     template<typename T>  
     struct void2type
     {
      static T invoke(void* ptr)
      {
       return if_<is_ptr<T>::value
          ,void2ptr<base_type<T>::type>
          ,if_<is_ref<T>::value
           ,void2ref<base_type<T>::type>
           ,void2val<base_type<T>::type>
          >::type
         >::type::invoke(ptr);
      }
     };

     template<typename T>  
     struct user2type { static T invoke(lua_State *L, int index) { return void2type<T>::invoke(lua_touserdata(L, index)); } };

     template<typename T>
     struct lua2enum { static T invoke(lua_State *L, int index) { return (T)(int)lua_tonumber(L, index); } };

     template<typename T>
     struct lua2object
     { 
      static T invoke(lua_State *L, int index) 
      { 
       if(!lua_isuserdata(L,index))
       {
        lua_pushstring(L, "no class at first argument. (forgot ':' expression ?)");
        lua_error(L);
       }
       return void2type<T>::invoke(user2type<user*>::invoke(L,index)->m_p); 
      } 
     };

     template<typename T>
     struct lua2type
     {
      static T invoke(lua_State *L, int index)
      {
       return if_<is_enum<T>::value
          ,lua2enum<T>
          ,lua2object<T> 
         >::type::invoke(L, index);
      }
     };

     struct user
     {
      user(void* p) : m_p(p) {}
      virtual ~user() {}
      void* m_p;
     };

     template<typename T>
     struct val2user : user
     {
      val2user() : user(new T) {}

      template<typename T1>
      val2user(T1 t1) : user(new T(t1)) {}

      template<typename T1, typename T2>
      val2user(T1 t1, T2 t2) : user(new T(t1, t2)) {}

      template<typename T1, typename T2, typename T3>
      val2user(T1 t1, T2 t2, T3 t3) : user(new T(t1, t2, t3)) {}

      ~val2user() { delete ((T*)m_p); }
     };

     template<typename T>
     struct ptr2user : user
     {
      ptr2user(T* t) : user((void*)t) {}
     };

     template<typename T>
     struct ref2user : user
     {
      ref2user(T& t) : user(&t) {}
     };

     // to lua
     template<typename T>
     struct val2lua { static void invoke(lua_State *L, T& input){ new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(input); } };
     template<typename T>
     struct ptr2lua { static void invoke(lua_State *L, T* input){ if(input) new(lua_newuserdata(L, sizeof(ptr2user<T>))) ptr2user<T>(input); else lua_pushnil(L); } };
     template<typename T>
     struct ref2lua { static void invoke(lua_State *L, T& input){ new(lua_newuserdata(L, sizeof(ref2user<T>))) ref2user<T>(input); } };

     template<typename T>
     struct enum2lua { static void invoke(lua_State *L, T val) { lua_pushnumber(L, (int)val); } };

     template<typename T>
     struct object2lua 
     { 
      static void invoke(lua_State *L, T val) 
      { 
       if_<is_ptr<T>::value
        ,ptr2lua<base_type<T>::type>
        ,if_<is_ref<T>::value
         ,ref2lua<base_type<T>::type>
         ,val2lua<base_type<T>::type>
        >::type
       >::type::invoke(L, val);

       class_<class_type<T>::type>::push_meta(L);
       lua_setmetatable(L, -2);
      } 
     };

     template<typename T>
     struct type2lua
     {
      static void invoke(lua_State *L, T val)
      {
       if_<is_enum<T>::value
        ,enum2lua<T>
        ,object2lua<T>
       >::type::invoke(L, val);
      };
     };

     //
     template<typename T>  
     T func_(lua_State *L)
     {
      return user2type<T>::invoke(L, lua_upvalueindex(1));
     }

     // arguments
     struct pop_ 
     {
      template<typename T>  
      static T invoke(lua_State *L, int index)    { return lua2type<T>::invoke(L, index);     }
      template<> 
      static char* invoke(lua_State *L, int index)   { return (char*)lua_tostring(L, index);     }
      template<> 
      static const char* invoke(lua_State *L, int index)  { return (const char*)lua_tostring(L, index);   }
      template<> 
      static char invoke(lua_State *L, int index)    { return (char)lua_tonumber(L, index);     }
      template<> 
      static unsigned char invoke(lua_State *L, int index) { return (unsigned char)lua_tonumber(L, index);   }
      template<> 
      static short invoke(lua_State *L, int index)   { return (short)lua_tonumber(L, index);     }
      template<> 
      static unsigned short invoke(lua_State *L, int index) { return (unsigned short)lua_tonumber(L, index);  }
      template<> 
      static long invoke(lua_State *L, int index)    { return (long)lua_tonumber(L, index);     }
      template<> 
      static unsigned long invoke(lua_State *L, int index) { return (unsigned long)lua_tonumber(L, index);   }
      template<> 
      static int invoke(lua_State *L, int index)    { return (int)lua_tonumber(L, index);     }
      template<> 
      static unsigned int invoke(lua_State *L, int index)  { return (unsigned int)lua_tonumber(L, index);   }
      template<> 
      static float invoke(lua_State *L, int index)   { return (float)lua_tonumber(L, index);     }
      template<> 
      static double invoke(lua_State *L, int index)   { return (double)lua_tonumber(L, index);    }
      template<> 
      static bool invoke(lua_State *L, int index)    { return lua_toboolean(L, index) != 0;     }
      template<> 
      static void invoke(lua_State *L, int index)    { return;            }
      template<> 
      static __int64 invoke(lua_State *L, int index)
      {
       if(lua_isnumber(L,index))
        return (__int64)lua_tonumber(L, index);
       else
        return *(__int64*)lua_touserdata(L, index);
      }
      template<> 
      static unsigned __int64 invoke(lua_State *L, int index)
      {
       if(lua_isnumber(L,index))
        return (unsigned __int64)lua_tonumber(L, index);
       else
        return *(unsigned __int64*)lua_touserdata(L, index);
      }
     };

     // return value
     struct push_
     {
      template<typename T>  
      static void invoke(lua_State *L, T ret)     { type2lua<T>::invoke(L, ret); }
      template<>
      static void invoke(lua_State *L, char ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned char ret)  { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, short ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned short ret) { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, long ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned long ret)  { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, int ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned int ret)  { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, float ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, double ret)   { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, char* ret)    { lua_pushstring(L, ret);  }
      template<>
      static void invoke(lua_State *L, const char* ret)  { lua_pushstring(L, ret);  }
      template<>
      static void invoke(lua_State *L, bool ret)    { lua_pushboolean(L, ret);  }
      template<>
      static void invoke(lua_State *L, lua_value* ret)  { if(ret) ret->to_lua(L); else lua_pushnil(L); }
      template<> 
      static void invoke(lua_State *L, __int64 ret)   
      { 
       *(__int64*)lua_newuserdata(L, sizeof(__int64)) = ret;
       lua_pushstring(L, "__s64");
       lua_gettable(L, LUA_GLOBALSINDEX);
       lua_setmetatable(L, -2);
      }
      template<> 
      static void invoke(lua_State *L, unsigned __int64 ret)
      {
       *(unsigned __int64*)lua_newuserdata(L, sizeof(unsigned __int64)) = ret;
       lua_pushstring(L, "__u64");
       lua_gettable(L, LUA_GLOBALSINDEX);
       lua_setmetatable(L, -2);
      }
     };

     template<typename T>
     struct ret_ { static const int value = 1; };
     template<>
     struct ret_<void> { static const int value = 0; };

     // caller
     template<typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
     struct caller
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3,T4,T5)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4),pop_::invoke<T5>(L,5))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3,T4,T5)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4),pop_::invoke<T5>(L,5)); }
     };

     template<typename T1, typename T2, typename T3, typename T4>
     struct caller<T1,T2,T3,T4> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3,T4)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3,T4)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4)); }
     };

     template<typename T1, typename T2, typename T3>
     struct caller<T1,T2,T3> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3)); }
     };

     template<typename T1, typename T2>
     struct caller<T1,T2> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2)); }
     };

     template<typename T1>
     struct caller<T1> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1)>(L)(pop_::invoke<T1>(L,1))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1)>(L)(pop_::invoke<T1>(L,1)); }
     };

     template<>
     struct caller<void> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)()>(L)()); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)()>(L)(); }
     };

     // function
     template<typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
     struct functor
     {
      template<typename RVal>
      static int invoke(lua_State *L) { caller<T1,T2,T3,T4,T5>::invoke<RVal>(L); return ret_<RVal>::value; }
     };

     template<typename RVal> 
     void push_func(lua_State *L, RVal (*func)())
     {
      lua_pushcclosure(L, functor<>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1> 
     void push_func(lua_State *L, RVal (*func)(T1))
     { 
      lua_pushcclosure(L, functor<T1>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1,class T2> 
     void push_func(lua_State *L, RVal (*func)(T1,T2))
     { 
      lua_pushcclosure(L, functor<T1,T2>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1,class T2, typename T3> 
     void push_func(lua_State *L, RVal (*func)(T1,T2,T3))
     { 
      lua_pushcclosure(L, functor<T1,T2,T3>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1,class T2, typename T3, typename T4> 
     void push_func(lua_State *L, RVal (*func)(T1,T2,T3,T4))
     { 
      lua_pushcclosure(L, functor<T1,T2,T3,T4>::invoke<RVal>, 1);
     }

     template<typename RVal,class T1,class T2, typename T3, typename T4, typename T5> 
     void push_func(lua_State *L, RVal (*func)(T1,T2,T3,T4,T5))
     { 
      lua_pushcclosure(L, functor<T1,T2,T3,T4,T5>::invoke<RVal>, 1);
     }

     // member variable
     template<typename T>
     T* this_(lua_State *L) 
     { 
      return pop_::invoke<T*>(L, 1); 
     }

     struct var_base
     {
      virtual void get(lua_State *L) = 0;
      virtual void set(lua_State *L) = 0;
     };

     template<typename T, typename V>
     struct mem_var : var_base
     {
      V T::*_var;
      mem_var(V T::*val) : _var(val) {}
      void get(lua_State *L) { push_::invoke(L, this_<T>(L)->*(_var));  }
      void set(lua_State *L) { this_<T>(L)->*(_var) = pop_::invoke<V>(L, 3); }
     };

     // member function
     template<typename T,class T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
     struct mem_caller
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3,T4,T5)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5),pop_::invoke<T5>(L,6))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3,T4,T5)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5),pop_::invoke<T5>(L,6)); }
     };

     template<typename T, typename T1, typename T2, typename T3, typename T4> 
     struct mem_caller<T,T1,T2,T3,T4>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3,T4)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3,T4)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5)); }
     };

     template<typename T, typename T1, typename T2, typename T3> 
     struct mem_caller<T,T1,T2,T3>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4)); }
     };

     template<typename T, typename T1, typename T2> 
     struct mem_caller<T,T1, T2>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3)); }
     };

     template<typename T, typename T1> 
     struct mem_caller<T,T1>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1)>(L))(pop_::invoke<T1>(L,2))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1)>(L))(pop_::invoke<T1>(L,2)); }
     };

     template<typename T> 
     struct mem_caller<T>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)()>(L))()); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)()>(L))(); }
     };
     
     // 
     template<typename T, typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void> 
     struct mem_functor
     {
      template<typename RVal>
      static int invoke(lua_State *L) { mem_caller<T,T1,T2,T3,T4,T5>::invoke<RVal>(L); return ret_<RVal>::value; }
     };

     template<typename RVal, typename T>
     void push_func(lua_State *L, RVal (T::*func)()) 
     { 
      lua_pushcclosure(L, mem_functor<T>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T>
     void push_func(lua_State *L, RVal (T::*func)() const) 
     { 
      lua_pushcclosure(L, mem_functor<T>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1>
     void push_func(lua_State *L, RVal (T::*func)(T1)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1>
     void push_func(lua_State *L, RVal (T::*func)(T1) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4,T5)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4,T5>::invoke<RVal>, 1); 
     }

     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4,T5) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4,T5>::invoke<RVal>, 1); 
     }

     // constructor
     template<typename T1=void, typename T2=void, typename T3=void, typename T4=void>
     struct constructor {};

     template<typename T1, typename T2, typename T3>
     struct constructor<T1,T2,T3>
     {
      template<typename T>
      static void invoke(lua_State *L)
      {
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4));
      }
     };


     template<typename T1, typename T2>
     struct constructor<T1,T2>
     {
      template<typename T>
      static void invoke(lua_State *L)
      {
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3));
      }
     };

     template<typename T1>
     struct constructor<T1>
     {
      template<typename T>
      static void invoke(lua_State *L)
      {
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2));
      }
     };

     template<>
     struct constructor<void>
     { 
      template<typename T>
      static void invoke(lua_State *L) 
      { 
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>();
      } 
     };

     template<typename T>
     struct creator
     {
      template<typename CONSTRUCTOR>
      static int invoke(lua_State *L) 
      { 
       CONSTRUCTOR::invoke<T>(L);
       class_<class_type<T>::type>::push_meta(L);
       lua_setmetatable(L, -2);

       return 1; 
      }
     };

     // destroyer
     template<typename T>
     struct destroyer
     {
      static int invoke(lua_State *L) 
      { 
       ((user*)lua_touserdata(L, 1))->~user();
       return 0;
      }
     };

     // get
     int get_var(lua_State *L);
     int set_var(lua_State *L);

     // Tinker Function
     template<typename F> 
     lua_obj def(const char* name, F func)
     { 
      lua_State *L = lua_state::L();
      lua_pushstring(L, name);
      lua_pushlightuserdata(L, func);
      push_func(L, func);
      lua_settable(L, LUA_GLOBALSINDEX);

      return lua_obj();
     }

     // Tinker Global
     template<typename T>
     lua_obj decl(const char* name, T object)
     {
      lua_State *L = lua_state::L();
      lua_pushstring(L, name);
      push_::invoke(L, object);
      lua_settable(L, LUA_GLOBALSINDEX);

      return lua_obj();
     }

     // Tinker Call
     template<typename RVal>
     RVal call(const char* name)
     {
      lua_State *L = lua_state::L();

      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      if(lua_isfunction(L,-1))
      {
       lua_pcall(L, 0, ret_<RVal>::value, 1);
      }
      else
      {
       lua_pushfstring(L, "lua_tinker : attempt to call global `%s' (not a function)", name);
       _exception(L);
      }

      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }

     template<typename RVal, typename T1>
     RVal call(const char* name, T1 arg)
     {
      lua_State *L = lua_state::L();

      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      push_::invoke(L, arg);
      lua_pcall(L, 1, ret_<RVal>::value, 1);
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }

     template<typename RVal, typename T1, typename T2>
     RVal call(const char* name, T1 arg1, T2 arg2)
     {
      lua_State *L = lua_state::L();

      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      push_::invoke(L, arg1);
      push_::invoke(L, arg2);
      lua_pcall(L, 2, ret_<RVal>::value, 1);
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }

     template<typename RVal, typename T1, typename T2, typename T3>
     RVal call(const char* name, T1 arg1, T2 arg2, T3 arg3)
     {
      lua_State *L = lua_state::L();

      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      push_::invoke(L, arg1);
      push_::invoke(L, arg2);
      push_::invoke(L, arg3);
      lua_pcall(L, 3, ret_<RVal>::value, 1);
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }

     // Tinker Class
     template<typename T>
     struct class_ : lua_obj
     {
      // initialize
      class_(const char* name) 
      : m_L(lua_state::L())
      { 
       _name(name);

       lua_pushstring(m_L, name);
       lua_newtable(m_L);

       lua_pushstring(m_L, "__name");
       lua_pushstring(m_L, name);
       lua_rawset(m_L, -3);

       lua_pushstring(m_L, "__index");
       lua_pushcclosure(m_L, get_var, 0);
       lua_rawset(m_L, -3);

       lua_pushstring(m_L, "__newindex");
       lua_pushcclosure(m_L, set_var, 0);
       lua_rawset(m_L, -3);

       lua_pushstring(m_L, "__gc");
       lua_pushcclosure(m_L, destroyer<T>::invoke, 0);
       lua_rawset(m_L, -3);

       lua_settable(m_L, LUA_GLOBALSINDEX);
      }

      // constructor
      template<typename CONSTRUCTOR>
      class_<T>& def(CONSTRUCTOR)
      {
       class_<class_type<T>::type>::push_meta(m_L);

       lua_newtable(m_L);
       lua_pushstring(m_L, "__call");
       lua_pushcclosure(m_L, creator<T>::invoke<CONSTRUCTOR>, 0);
       lua_rawset(m_L, -3);
       lua_setmetatable(m_L, -2);
       lua_pop(m_L,1);
       return *this; 
      }

      // inheritence
      template<typename P>
      class_<T>& inh()
      {
       class_<class_type<T>::type>::push_meta(m_L);
       lua_pushstring(m_L, "__parent");
       class_<class_type<P>::type>::push_meta(m_L);
       lua_rawset(m_L, -3);
       lua_pop(m_L,1);
       return *this; 
      }

      // functions
      template<typename F>
      class_<T>& def(const char* name, F func) 
      { 
       class_<class_type<T>::type>::push_meta(m_L);

       lua_pushstring(m_L, name);
       new(lua_newuserdata(m_L,sizeof(F))) F(func);
       push_func(m_L, func);
       lua_rawset(m_L, -3);

       lua_pop(m_L,1);
       return *this; 
      }

      // variables
      template<typename BASE, typename VAR>
      class_<T>& def_readwrite(const char* name, VAR BASE::*val) 
      { 
       class_<class_type<T>::type>::push_meta(m_L);

       lua_pushstring(m_L, name);
       new(lua_newuserdata(m_L,sizeof(mem_var<BASE,VAR>))) mem_var<BASE,VAR>(val);
       lua_rawset(m_L, -3);

       lua_pop(m_L,1);
       return *this; 
      }

      // metatable
      static void push_meta(lua_State *L)
      {
       const char* name = _name();
       if(name[0])
       {
        lua_pushstring(L, name);
        lua_gettable(L, LUA_GLOBALSINDEX);
       }
       else
       {
        lua_pushnil(L);
       }
      }

      // global name
      static const char* _name(const char* name = NULL)
      {
       static char temp[256] = "";
       if(name) strcpy(temp, name);
       return temp;
      }

      lua_State* m_L;     
     };

    } // namespace lua_tinker

    #endif //_LUA_TINKER_H_

     

    // Lua Test.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include "lua_tinker/lua_tinker.h"

    struct A
    {
     A(int v) : value(v) {}
     int value;
    };

    struct base
    {
     base() {}

     const char* is_base(){ return "this is base"; }
    };

    class test : public base
    {
    public:
     test(int val) : _test(val) {}
     ~test() {}

     const char* is_test(){ return "this is test"; }

     void ret_void() {}
     int ret_int()    { return _test;   }
     int ret_mul(int m) const { return _test * m;  }
     A get()      { return A(_test);  }
     void set(A a)    { _test = a.value;  }

     int _test;
    };

    test g_test(11);

    class parent : public lua_tinker::lua_value
    {
    public:
     void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐

     virtual const char* name() { return "parent"; }

     int m_parent;
    };

    class child : public parent
    {
    public:
     void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐

     const char* name() { return "child"; }

     int m_child;
    };

    class grandchild : public child
    {
    public:
     void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐

     const char* name() { return "grandchild"; }

     int m_grandchild;
    };

    lua_tinker::lua_value* GetChild(int n)
    {
     static parent _parent;
     static child _child;
     static grandchild _grandchild;

     if(n == 0)
      return &_parent;
     else if(n == 1)
      return &_child;
     else
      return &_grandchild;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
     lua_State* L = lua_open();

     // init Lua
     luaopen_base(L);
     luaopen_string(L);
     luaopen_table(L);

     lua_settop(L, 0);

     // LuaTinker
     lua_tinker::lua_state::open(L);

     lua_tinker::class_<base>("base")
      .def("is_base", &base::is_base)
      ;

     lua_tinker::class_<test>("test")
      .inh<base>()
      .def(lua_tinker::constructor<int>())
      .def("is_test", &test::is_test)
      .def("ret_void", &test::ret_void)
      .def("ret_int", &test::ret_int)
      .def("ret_mul", &test::ret_mul)
      .def("get", &test::get)
      .def("set", &test::set)
      .def_readwrite("_test", &test::_test)
      ;
     lua_tinker::decl("g_test", &g_test);

     lua_tinker::class_<parent>("parent")
      .def("name", &parent::name)
      .def_readwrite("m_parent", &parent::m_parent)
      ;

     lua_tinker::class_<child>("child")
      .inh<parent>()
      .def_readwrite("m_child", &child::m_child)
      ;

     lua_tinker::class_<grandchild>("grandchild")
      .inh<child>()
      .def_readwrite("m_grandchild", &grandchild::m_grandchild)
      ;

     lua_tinker::def("GetChild", GetChild);


     // lua_tinker 龋免 抛胶飘
     lua_tinker::dofile(L, "test.lua");

     lua_tinker::call<void>("print", "-------------------------- call<>");
     lua_tinker::call<void>("dir", g_test);
     lua_tinker::call<void>("print", "-------------------------- call<> finished");

     char temp[1024];
     while(true)
     {
      printf(">");
      if(stricmp(gets(temp), "quit") == 0)
       break;
      lua_tinker::dostring(L, temp);
     }

     // close Lua
     lua_close(L);

     return 0;
    }

    展开全文
  • luatinker 的使用

    千次阅读 2014-07-04 16:13:49
    LuaTinker的作者是Kwon-il Lee韩国人写的,最新的版本是0.2.C,这个C++ wrapper For Lua能够方便和 快捷与C/C++通信,LuaTinker参考了luabind和luaplus的特征写的,虽然没有bindlua和luaplus这本强大 和提供很多功能...
    <span style="font-size:18px;">LuaTinker的作者是Kwon-il Lee韩国人写的,最新的版本是0.2.C,这个C++ wrapper For Lua能够方便和
    
    快捷与C/C++通信,LuaTinker参考了luabind和luaplus的特征写的,虽然没有bindlua和luaplus这本强大
    
    和提供很多功能,LuaTinker的实现只有两个文件,但是LuaTinker提供的基本能够满足大部的要求,用户
    
    还可以对它进一步的扩充,而且用于游戏上特为方便,以下是LuaTinker使用C++结构和类的例子:
    
    // 一个基类
    struct base
    {
     base() {}
    
     const char* is_base(){ return "this is base"; }
    };
    
    // 一个测试类
    class test : public base
    {
    public:
     test(int val) : _test(val) {}
     ~test() {}
    
     const char* is_test(){ return "this is test"; }
    
     void ret_void() {}
     int ret_int()   { return _test;   }
     int ret_mul(int m) const { return _test * m;  }
     A get()    { return A(_test);  }
     void set(A a)   { _test = a.value;  }
     int _test;
    };
    
    int main()
    {
     // 注册base类型到LUA
     lua_tinker::class_<base>("base")
      .def("is_base", &base::is_base)
      ;
     
     // 注册test类型到LUA,注册test的成员函数和成员变量
     lua_tinker::class_<test>("test")
      .inh<base>() // 注册继承类
      .def(lua_tinker::constructor<int>()) //注册构造函数
      .def("is_test", &test::is_test)           // 注册成员函数
      .def("ret_void", &test::ret_void)
      .def("ret_int", &test::ret_int)
      .def("ret_mul", &test::ret_mul)
      .def("get", &test::get)
      .def("set", &test::set)
      .def_readwrite("_test", &test::_test) // 注册成员变量
      ;
    
     test g_test(11);
     
     lua_tinker::decl("g_test", &g_test);
     
    }
    
    // Lua脚本
    temp = test(4)  创建一个test类
    print(temp._test) 打印test的_test成员
    
    print(g_test)     
    print(g_test._test) 打印g_test的成员变量_test
    print(g_test:is_test()) 输出信息  
    print(g_test:ret_int()) 返回g_test的成员变量_test
    
    这么几句就能够方便的使用C/C++定义的结构或类,下一篇将会介绍其他的用法.
    介绍完用法之后会从结构上分析lua_tinker的结构和设计.
    
     
    
     
    
    // lua_tinker.h
    //
    // LuaTinker - Simple and light C++ wrapper for Lua.
    //
    // Copyright (c) 2005 Kwon-il Lee (zupet@hitel.net)
    // 
    // please check Licence.txt file for licence and legal issues.
    
    #if !defined(_LUA_TINKER_H_)
    #define _LUA_TINKER_H_
    
    #include <new>
    
    namespace lua_tinker
    {
     // debug helpers
     void enum_stack(lua_State *L, int start=0);
     int  _exception(lua_State *L);
    
     void dofile(const char *filename);
     void dostring(const char* buff);
     void dobuffer(const char* buff, size_t sz);
    
     void dofile(lua_State *L, const char *filename);
     void dostring(lua_State *L, const char* buff);
     void dobuffer(lua_State *L, const char* buff, size_t sz);
    
     // basic Object
     struct lua_state
     {
      static void open(lua_State *in)
      { 
       L(in); 
       init_s64(in);
       init_u64(in);
      }
    
      static lua_State* L(lua_State *in=NULL);
      static void   init_s64(lua_State *L);
      static void   init_u64(lua_State *L);
     };
    
     // for LuaBind
     struct luabind : lua_state
     {
     };
    
     struct lua_obj
     {
      lua_obj& operator,(const lua_obj& obj) { return *this; }
     };
    
     struct module
     {
      module(lua_State *L){}
      void operator[](const lua_obj& obj){}
     };
    
     struct lua_value
     {
      virtual void to_lua(lua_State *L) = 0;
     };
    
     // type trait
     template<typename T> struct class_;
    
     template<bool C, typename A, typename B> 
     struct if_ {};
     template<typename A, typename B> 
     struct if_<true, A, B> { typedef A type; };
     template<typename A, typename B> 
     struct if_<false, A, B> { typedef B type; };
    
     template<typename A>
     struct is_ptr { static const bool value = false; };
     template<typename A>
     struct is_ptr<A*> { static const bool value = true; };
    
     template<typename A>
     struct is_ref { static const bool value = false; };
     template<typename A>
     struct is_ref<A&> { static const bool value = true; };
    
     template<typename A>
     struct remove_const { typedef A type; };
     template<typename A>
     struct remove_const<const A> { typedef A type; };
    
     template<typename A>
     struct base_type { typedef A type; };
     template<typename A>
     struct base_type<A*> { typedef A type; };
     template<typename A>
     struct base_type<A&> { typedef A type; };
    
     template<typename A>
     struct class_type { typedef typename remove_const<typename base_type<A>::type>::type type; };
     
     /
     enum { no = 1, yes = 2 }; 
     typedef char (& no_type )[no]; 
     typedef char (& yes_type)[yes];
    
     struct int_conv_type { int_conv_type(int); };
    
     no_type int_conv_tester (...); 
     yes_type int_conv_tester (int_conv_type);
    
     no_type vfnd_ptr_tester (const volatile char *); 
     no_type vfnd_ptr_tester (const volatile short *); 
     no_type vfnd_ptr_tester (const volatile int *); 
     no_type vfnd_ptr_tester (const volatile long *); 
     no_type vfnd_ptr_tester (const volatile double *); 
     no_type vfnd_ptr_tester (const volatile float *); 
     no_type vfnd_ptr_tester (const volatile bool *); 
     yes_type vfnd_ptr_tester (const volatile void *);
    
     template <typename T> T* add_ptr(T&);
    
     template <bool C> struct bool_to_yesno { typedef no_type type; }; 
     template <> struct bool_to_yesno<true> { typedef yes_type type; };
    
     template <typename T> 
     struct is_enum 
     { 
      static T arg; 
      static const bool value = ( (sizeof(int_conv_tester(arg)) == sizeof(yes_type)) && (sizeof(vfnd_ptr_tester(add_ptr(arg))) == sizeof(yes_type)) ); 
     }; 
     /
    
     // from lua
     template<typename T>
     struct void2val { static T invoke(void* input){ return *(T*)input; } };
     template<typename T>
     struct void2ptr { static T* invoke(void* input){ return (T*)input; } };
     template<typename T>
     struct void2ref { static T& invoke(void* input){ return *(T*)input; } };
    
     template<typename T>  
     struct void2type
     {
      static T invoke(void* ptr)
      {
       return if_<is_ptr<T>::value
          ,void2ptr<base_type<T>::type>
          ,if_<is_ref<T>::value
           ,void2ref<base_type<T>::type>
           ,void2val<base_type<T>::type>
          >::type
         >::type::invoke(ptr);
      }
     };
    
     template<typename T>  
     struct user2type { static T invoke(lua_State *L, int index) { return void2type<T>::invoke(lua_touserdata(L, index)); } };
    
     template<typename T>
     struct lua2enum { static T invoke(lua_State *L, int index) { return (T)(int)lua_tonumber(L, index); } };
    
     template<typename T>
     struct lua2object
     { 
      static T invoke(lua_State *L, int index) 
      { 
       if(!lua_isuserdata(L,index))
       {
        lua_pushstring(L, "no class at first argument. (forgot ':' expression ?)");
        lua_error(L);
       }
       return void2type<T>::invoke(user2type<user*>::invoke(L,index)->m_p); 
      } 
     };
    
     template<typename T>
     struct lua2type
     {
      static T invoke(lua_State *L, int index)
      {
       return if_<is_enum<T>::value
          ,lua2enum<T>
          ,lua2object<T> 
         >::type::invoke(L, index);
      }
     };
    
     struct user
     {
      user(void* p) : m_p(p) {}
      virtual ~user() {}
      void* m_p;
     };
    
     template<typename T>
     struct val2user : user
     {
      val2user() : user(new T) {}
    
      template<typename T1>
      val2user(T1 t1) : user(new T(t1)) {}
    
      template<typename T1, typename T2>
      val2user(T1 t1, T2 t2) : user(new T(t1, t2)) {}
    
      template<typename T1, typename T2, typename T3>
      val2user(T1 t1, T2 t2, T3 t3) : user(new T(t1, t2, t3)) {}
    
      ~val2user() { delete ((T*)m_p); }
     };
    
     template<typename T>
     struct ptr2user : user
     {
      ptr2user(T* t) : user((void*)t) {}
     };
    
     template<typename T>
     struct ref2user : user
     {
      ref2user(T& t) : user(&t) {}
     };
    
     // to lua
     template<typename T>
     struct val2lua { static void invoke(lua_State *L, T& input){ new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(input); } };
     template<typename T>
     struct ptr2lua { static void invoke(lua_State *L, T* input){ if(input) new(lua_newuserdata(L, sizeof(ptr2user<T>))) ptr2user<T>(input); else lua_pushnil(L); } };
     template<typename T>
     struct ref2lua { static void invoke(lua_State *L, T& input){ new(lua_newuserdata(L, sizeof(ref2user<T>))) ref2user<T>(input); } };
    
     template<typename T>
     struct enum2lua { static void invoke(lua_State *L, T val) { lua_pushnumber(L, (int)val); } };
    
     template<typename T>
     struct object2lua 
     { 
      static void invoke(lua_State *L, T val) 
      { 
       if_<is_ptr<T>::value
        ,ptr2lua<base_type<T>::type>
        ,if_<is_ref<T>::value
         ,ref2lua<base_type<T>::type>
         ,val2lua<base_type<T>::type>
        >::type
       >::type::invoke(L, val);
    
       class_<class_type<T>::type>::push_meta(L);
       lua_setmetatable(L, -2);
      } 
     };
    
     template<typename T>
     struct type2lua
     {
      static void invoke(lua_State *L, T val)
      {
       if_<is_enum<T>::value
        ,enum2lua<T>
        ,object2lua<T>
       >::type::invoke(L, val);
      };
     };
    
     //
     template<typename T>  
     T func_(lua_State *L)
     {
      return user2type<T>::invoke(L, lua_upvalueindex(1));
     }
    
     // arguments
     struct pop_ 
     {
      template<typename T>  
      static T invoke(lua_State *L, int index)    { return lua2type<T>::invoke(L, index);     }
      template<> 
      static char* invoke(lua_State *L, int index)   { return (char*)lua_tostring(L, index);     }
      template<> 
      static const char* invoke(lua_State *L, int index)  { return (const char*)lua_tostring(L, index);   }
      template<> 
      static char invoke(lua_State *L, int index)    { return (char)lua_tonumber(L, index);     }
      template<> 
      static unsigned char invoke(lua_State *L, int index) { return (unsigned char)lua_tonumber(L, index);   }
      template<> 
      static short invoke(lua_State *L, int index)   { return (short)lua_tonumber(L, index);     }
      template<> 
      static unsigned short invoke(lua_State *L, int index) { return (unsigned short)lua_tonumber(L, index);  }
      template<> 
      static long invoke(lua_State *L, int index)    { return (long)lua_tonumber(L, index);     }
      template<> 
      static unsigned long invoke(lua_State *L, int index) { return (unsigned long)lua_tonumber(L, index);   }
      template<> 
      static int invoke(lua_State *L, int index)    { return (int)lua_tonumber(L, index);     }
      template<> 
      static unsigned int invoke(lua_State *L, int index)  { return (unsigned int)lua_tonumber(L, index);   }
      template<> 
      static float invoke(lua_State *L, int index)   { return (float)lua_tonumber(L, index);     }
      template<> 
      static double invoke(lua_State *L, int index)   { return (double)lua_tonumber(L, index);    }
      template<> 
      static bool invoke(lua_State *L, int index)    { return lua_toboolean(L, index) != 0;     }
      template<> 
      static void invoke(lua_State *L, int index)    { return;            }
      template<> 
      static __int64 invoke(lua_State *L, int index)
      {
       if(lua_isnumber(L,index))
        return (__int64)lua_tonumber(L, index);
       else
        return *(__int64*)lua_touserdata(L, index);
      }
      template<> 
      static unsigned __int64 invoke(lua_State *L, int index)
      {
       if(lua_isnumber(L,index))
        return (unsigned __int64)lua_tonumber(L, index);
       else
        return *(unsigned __int64*)lua_touserdata(L, index);
      }
     };
    
     // return value
     struct push_
     {
      template<typename T>  
      static void invoke(lua_State *L, T ret)     { type2lua<T>::invoke(L, ret); }
      template<>
      static void invoke(lua_State *L, char ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned char ret)  { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, short ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned short ret) { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, long ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned long ret)  { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, int ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, unsigned int ret)  { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, float ret)    { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, double ret)   { lua_pushnumber(L, ret);  }
      template<>
      static void invoke(lua_State *L, char* ret)    { lua_pushstring(L, ret);  }
      template<>
      static void invoke(lua_State *L, const char* ret)  { lua_pushstring(L, ret);  }
      template<>
      static void invoke(lua_State *L, bool ret)    { lua_pushboolean(L, ret);  }
      template<>
      static void invoke(lua_State *L, lua_value* ret)  { if(ret) ret->to_lua(L); else lua_pushnil(L); }
      template<> 
      static void invoke(lua_State *L, __int64 ret)   
      { 
       *(__int64*)lua_newuserdata(L, sizeof(__int64)) = ret;
       lua_pushstring(L, "__s64");
       lua_gettable(L, LUA_GLOBALSINDEX);
       lua_setmetatable(L, -2);
      }
      template<> 
      static void invoke(lua_State *L, unsigned __int64 ret)
      {
       *(unsigned __int64*)lua_newuserdata(L, sizeof(unsigned __int64)) = ret;
       lua_pushstring(L, "__u64");
       lua_gettable(L, LUA_GLOBALSINDEX);
       lua_setmetatable(L, -2);
      }
     };
    
     template<typename T>
     struct ret_ { static const int value = 1; };
     template<>
     struct ret_<void> { static const int value = 0; };
    
     // caller
     template<typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
     struct caller
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3,T4,T5)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4),pop_::invoke<T5>(L,5))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3,T4,T5)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4),pop_::invoke<T5>(L,5)); }
     };
    
     template<typename T1, typename T2, typename T3, typename T4>
     struct caller<T1,T2,T3,T4> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3,T4)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3,T4)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3),pop_::invoke<T4>(L,4)); }
     };
    
     template<typename T1, typename T2, typename T3>
     struct caller<T1,T2,T3> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2,T3)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2,T3)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2),pop_::invoke<T3>(L,3)); }
     };
    
     template<typename T1, typename T2>
     struct caller<T1,T2> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1,T2)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1,T2)>(L)(pop_::invoke<T1>(L,1),pop_::invoke<T2>(L,2)); }
     };
    
     template<typename T1>
     struct caller<T1> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)(T1)>(L)(pop_::invoke<T1>(L,1))); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)(T1)>(L)(pop_::invoke<T1>(L,1)); }
     };
    
     template<>
     struct caller<void> 
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,func_<RVal(*)()>(L)()); }
      template<>
      static void invoke<void>(lua_State *L) { func_<void(*)()>(L)(); }
     };
    
     // function
     template<typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
     struct functor
     {
      template<typename RVal>
      static int invoke(lua_State *L) { caller<T1,T2,T3,T4,T5>::invoke<RVal>(L); return ret_<RVal>::value; }
     };
    
     template<typename RVal> 
     void push_func(lua_State *L, RVal (*func)())
     {
      lua_pushcclosure(L, functor<>::invoke<RVal>, 1);
     }
    
     template<typename RVal,class T1> 
     void push_func(lua_State *L, RVal (*func)(T1))
     { 
      lua_pushcclosure(L, functor<T1>::invoke<RVal>, 1);
     }
    
     template<typename RVal,class T1,class T2> 
     void push_func(lua_State *L, RVal (*func)(T1,T2))
     { 
      lua_pushcclosure(L, functor<T1,T2>::invoke<RVal>, 1);
     }
    
     template<typename RVal,class T1,class T2, typename T3> 
     void push_func(lua_State *L, RVal (*func)(T1,T2,T3))
     { 
      lua_pushcclosure(L, functor<T1,T2,T3>::invoke<RVal>, 1);
     }
    
     template<typename RVal,class T1,class T2, typename T3, typename T4> 
     void push_func(lua_State *L, RVal (*func)(T1,T2,T3,T4))
     { 
      lua_pushcclosure(L, functor<T1,T2,T3,T4>::invoke<RVal>, 1);
     }
    
     template<typename RVal,class T1,class T2, typename T3, typename T4, typename T5> 
     void push_func(lua_State *L, RVal (*func)(T1,T2,T3,T4,T5))
     { 
      lua_pushcclosure(L, functor<T1,T2,T3,T4,T5>::invoke<RVal>, 1);
     }
    
     // member variable
     template<typename T>
     T* this_(lua_State *L) 
     { 
      return pop_::invoke<T*>(L, 1); 
     }
    
     struct var_base
     {
      virtual void get(lua_State *L) = 0;
      virtual void set(lua_State *L) = 0;
     };
    
     template<typename T, typename V>
     struct mem_var : var_base
     {
      V T::*_var;
      mem_var(V T::*val) : _var(val) {}
      void get(lua_State *L) { push_::invoke(L, this_<T>(L)->*(_var));  }
      void set(lua_State *L) { this_<T>(L)->*(_var) = pop_::invoke<V>(L, 3); }
     };
    
     // member function
     template<typename T,class T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void>
     struct mem_caller
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3,T4,T5)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5),pop_::invoke<T5>(L,6))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3,T4,T5)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5),pop_::invoke<T5>(L,6)); }
     };
    
     template<typename T, typename T1, typename T2, typename T3, typename T4> 
     struct mem_caller<T,T1,T2,T3,T4>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3,T4)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3,T4)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4),pop_::invoke<T4>(L,5)); }
     };
    
     template<typename T, typename T1, typename T2, typename T3> 
     struct mem_caller<T,T1,T2,T3>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2,T3)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2,T3)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4)); }
     };
    
     template<typename T, typename T1, typename T2> 
     struct mem_caller<T,T1, T2>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1,T2)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1,T2)>(L))(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3)); }
     };
    
     template<typename T, typename T1> 
     struct mem_caller<T,T1>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)(T1)>(L))(pop_::invoke<T1>(L,2))); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)(T1)>(L))(pop_::invoke<T1>(L,2)); }
     };
    
     template<typename T> 
     struct mem_caller<T>
     {
      template<typename RVal>
      static void invoke(lua_State *L) { push_::invoke(L,(this_<T>(L)->*func_<RVal(T::*)()>(L))()); }
      template<>
      static void invoke<void>(lua_State *L)  { (this_<T>(L)->*func_<void(T::*)()>(L))(); }
     };
     
     // 
     template<typename T, typename T1=void, typename T2=void, typename T3=void, typename T4=void, typename T5=void> 
     struct mem_functor
     {
      template<typename RVal>
      static int invoke(lua_State *L) { mem_caller<T,T1,T2,T3,T4,T5>::invoke<RVal>(L); return ret_<RVal>::value; }
     };
    
     template<typename RVal, typename T>
     void push_func(lua_State *L, RVal (T::*func)()) 
     { 
      lua_pushcclosure(L, mem_functor<T>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T>
     void push_func(lua_State *L, RVal (T::*func)() const) 
     { 
      lua_pushcclosure(L, mem_functor<T>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1>
     void push_func(lua_State *L, RVal (T::*func)(T1)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1>
     void push_func(lua_State *L, RVal (T::*func)(T1) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1, typename T2>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1, typename T2>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1, typename T2, typename T3>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1, typename T2, typename T3>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4,T5)) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4,T5>::invoke<RVal>, 1); 
     }
    
     template<typename RVal, typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
     void push_func(lua_State *L, RVal (T::*func)(T1,T2,T3,T4,T5) const) 
     { 
      lua_pushcclosure(L, mem_functor<T,T1,T2,T3,T4,T5>::invoke<RVal>, 1); 
     }
    
     // constructor
     template<typename T1=void, typename T2=void, typename T3=void, typename T4=void>
     struct constructor {};
    
     template<typename T1, typename T2, typename T3>
     struct constructor<T1,T2,T3>
     {
      template<typename T>
      static void invoke(lua_State *L)
      {
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3),pop_::invoke<T3>(L,4));
      }
     };
    
    
     template<typename T1, typename T2>
     struct constructor<T1,T2>
     {
      template<typename T>
      static void invoke(lua_State *L)
      {
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2),pop_::invoke<T2>(L,3));
      }
     };
    
     template<typename T1>
     struct constructor<T1>
     {
      template<typename T>
      static void invoke(lua_State *L)
      {
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>(pop_::invoke<T1>(L,2));
      }
     };
    
     template<>
     struct constructor<void>
     { 
      template<typename T>
      static void invoke(lua_State *L) 
      { 
       new(lua_newuserdata(L, sizeof(val2user<T>))) val2user<T>();
      } 
     };
    
     template<typename T>
     struct creator
     {
      template<typename CONSTRUCTOR>
      static int invoke(lua_State *L) 
      { 
       CONSTRUCTOR::invoke<T>(L);
       class_<class_type<T>::type>::push_meta(L);
       lua_setmetatable(L, -2);
    
       return 1; 
      }
     };
    
     // destroyer
     template<typename T>
     struct destroyer
     {
      static int invoke(lua_State *L) 
      { 
       ((user*)lua_touserdata(L, 1))->~user();
       return 0;
      }
     };
    
     // get
     int get_var(lua_State *L);
     int set_var(lua_State *L);
    
     // Tinker Function
     template<typename F> 
     lua_obj def(const char* name, F func)
     { 
      lua_State *L = lua_state::L();
      lua_pushstring(L, name);
      lua_pushlightuserdata(L, func);
      push_func(L, func);
      lua_settable(L, LUA_GLOBALSINDEX);
    
      return lua_obj();
     }
    
     // Tinker Global
     template<typename T>
     lua_obj decl(const char* name, T object)
     {
      lua_State *L = lua_state::L();
      lua_pushstring(L, name);
      push_::invoke(L, object);
      lua_settable(L, LUA_GLOBALSINDEX);
    
      return lua_obj();
     }
    
     // Tinker Call
     template<typename RVal>
     RVal call(const char* name)
     {
      lua_State *L = lua_state::L();
    
      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      if(lua_isfunction(L,-1))
      {
       lua_pcall(L, 0, ret_<RVal>::value, 1);
      }
      else
      {
       lua_pushfstring(L, "lua_tinker : attempt to call global `%s' (not a function)", name);
       _exception(L);
      }
    
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }
    
     template<typename RVal, typename T1>
     RVal call(const char* name, T1 arg)
     {
      lua_State *L = lua_state::L();
    
      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      push_::invoke(L, arg);
      lua_pcall(L, 1, ret_<RVal>::value, 1);
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }
    
     template<typename RVal, typename T1, typename T2>
     RVal call(const char* name, T1 arg1, T2 arg2)
     {
      lua_State *L = lua_state::L();
    
      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      push_::invoke(L, arg1);
      push_::invoke(L, arg2);
      lua_pcall(L, 2, ret_<RVal>::value, 1);
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }
    
     template<typename RVal, typename T1, typename T2, typename T3>
     RVal call(const char* name, T1 arg1, T2 arg2, T3 arg3)
     {
      lua_State *L = lua_state::L();
    
      lua_pushcclosure(L, _exception, 0);
      lua_pushstring(L, name);
      lua_gettable(L, LUA_GLOBALSINDEX);
      push_::invoke(L, arg1);
      push_::invoke(L, arg2);
      push_::invoke(L, arg3);
      lua_pcall(L, 3, ret_<RVal>::value, 1);
      lua_remove(L, 1);
      return pop_::invoke<RVal>(L, -1);
     }
    
     // Tinker Class
     template<typename T>
     struct class_ : lua_obj
     {
      // initialize
      class_(const char* name) 
      : m_L(lua_state::L())
      { 
       _name(name);
    
       lua_pushstring(m_L, name);
       lua_newtable(m_L);
    
       lua_pushstring(m_L, "__name");
       lua_pushstring(m_L, name);
       lua_rawset(m_L, -3);
    
       lua_pushstring(m_L, "__index");
       lua_pushcclosure(m_L, get_var, 0);
       lua_rawset(m_L, -3);
    
       lua_pushstring(m_L, "__newindex");
       lua_pushcclosure(m_L, set_var, 0);
       lua_rawset(m_L, -3);
    
       lua_pushstring(m_L, "__gc");
       lua_pushcclosure(m_L, destroyer<T>::invoke, 0);
       lua_rawset(m_L, -3);
    
       lua_settable(m_L, LUA_GLOBALSINDEX);
      }
    
      // constructor
      template<typename CONSTRUCTOR>
      class_<T>& def(CONSTRUCTOR)
      {
       class_<class_type<T>::type>::push_meta(m_L);
    
       lua_newtable(m_L);
       lua_pushstring(m_L, "__call");
       lua_pushcclosure(m_L, creator<T>::invoke<CONSTRUCTOR>, 0);
       lua_rawset(m_L, -3);
       lua_setmetatable(m_L, -2);
       lua_pop(m_L,1);
       return *this; 
      }
    
      // inheritence
      template<typename P>
      class_<T>& inh()
      {
       class_<class_type<T>::type>::push_meta(m_L);
       lua_pushstring(m_L, "__parent");
       class_<class_type<P>::type>::push_meta(m_L);
       lua_rawset(m_L, -3);
       lua_pop(m_L,1);
       return *this; 
      }
    
      // functions
      template<typename F>
      class_<T>& def(const char* name, F func) 
      { 
       class_<class_type<T>::type>::push_meta(m_L);
    
       lua_pushstring(m_L, name);
       new(lua_newuserdata(m_L,sizeof(F))) F(func);
       push_func(m_L, func);
       lua_rawset(m_L, -3);
    
       lua_pop(m_L,1);
       return *this; 
      }
    
      // variables
      template<typename BASE, typename VAR>
      class_<T>& def_readwrite(const char* name, VAR BASE::*val) 
      { 
       class_<class_type<T>::type>::push_meta(m_L);
    
       lua_pushstring(m_L, name);
       new(lua_newuserdata(m_L,sizeof(mem_var<BASE,VAR>))) mem_var<BASE,VAR>(val);
       lua_rawset(m_L, -3);
    
       lua_pop(m_L,1);
       return *this; 
      }
    
      // metatable
      static void push_meta(lua_State *L)
      {
       const char* name = _name();
       if(name[0])
       {
        lua_pushstring(L, name);
        lua_gettable(L, LUA_GLOBALSINDEX);
       }
       else
       {
        lua_pushnil(L);
       }
      }
    
      // global name
      static const char* _name(const char* name = NULL)
      {
       static char temp[256] = "";
       if(name) strcpy(temp, name);
       return temp;
      }
    
      lua_State* m_L;     
     };
    
    } // namespace lua_tinker
    
    #endif //_LUA_TINKER_H_
    
     
    
    // Lua Test.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include "lua_tinker/lua_tinker.h"
    
    struct A
    {
     A(int v) : value(v) {}
     int value;
    };
    
    struct base
    {
     base() {}
    
     const char* is_base(){ return "this is base"; }
    };
    
    class test : public base
    {
    public:
     test(int val) : _test(val) {}
     ~test() {}
    
     const char* is_test(){ return "this is test"; }
    
     void ret_void() {}
     int ret_int()    { return _test;   }
     int ret_mul(int m) const { return _test * m;  }
     A get()      { return A(_test);  }
     void set(A a)    { _test = a.value;  }
    
     int _test;
    };
    
    test g_test(11);
    
    class parent : public lua_tinker::lua_value
    {
    public:
     void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐
    
     virtual const char* name() { return "parent"; }
    
     int m_parent;
    };
    
    class child : public parent
    {
    public:
     void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐
    
     const char* name() { return "child"; }
    
     int m_child;
    };
    
    class grandchild : public child
    {
    public:
     void to_lua(lua_State* L) { lua_tinker::push_::invoke(L, this); } // lua 肺 傈崔 窃荐
    
     const char* name() { return "grandchild"; }
    
     int m_grandchild;
    };
    
    lua_tinker::lua_value* GetChild(int n)
    {
     static parent _parent;
     static child _child;
     static grandchild _grandchild;
    
     if(n == 0)
      return &_parent;
     else if(n == 1)
      return &_child;
     else
      return &_grandchild;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
     lua_State* L = lua_open();
    
     // init Lua
     luaopen_base(L);
     luaopen_string(L);
     luaopen_table(L);
    
     lua_settop(L, 0);
    
     // LuaTinker
     lua_tinker::lua_state::open(L);
    
     lua_tinker::class_<base>("base")
      .def("is_base", &base::is_base)
      ;
    
     lua_tinker::class_<test>("test")
      .inh<base>()
      .def(lua_tinker::constructor<int>())
      .def("is_test", &test::is_test)
      .def("ret_void", &test::ret_void)
      .def("ret_int", &test::ret_int)
      .def("ret_mul", &test::ret_mul)
      .def("get", &test::get)
      .def("set", &test::set)
      .def_readwrite("_test", &test::_test)
      ;
     lua_tinker::decl("g_test", &g_test);
    
     lua_tinker::class_<parent>("parent")
      .def("name", &parent::name)
      .def_readwrite("m_parent", &parent::m_parent)
      ;
    
     lua_tinker::class_<child>("child")
      .inh<parent>()
      .def_readwrite("m_child", &child::m_child)
      ;
    
     lua_tinker::class_<grandchild>("grandchild")
      .inh<child>()
      .def_readwrite("m_grandchild", &grandchild::m_grandchild)
      ;
    
     lua_tinker::def("GetChild", GetChild);
    
    
     // lua_tinker 龋免 抛胶飘
     lua_tinker::dofile(L, "test.lua");
    
     lua_tinker::call<void>("print", "-------------------------- call<>");
     lua_tinker::call<void>("dir", g_test);
     lua_tinker::call<void>("print", "-------------------------- call<> finished");
    
     char temp[1024];
     while(true)
     {
      printf(">");
      if(stricmp(gets(temp), "quit") == 0)
       break;
      lua_tinker::dostring(L, temp);
     }
    
     // close Lua
     lua_close(L);
    
     return 0;
    }</span>

    展开全文
  • c++ 封装luatinker

    千次阅读 2014-07-21 16:14:20
    闲来无聊,把luatinker封装了一层,效果还不错,哈哈。。。。。
  • luatinker_0.5c

    2011-03-25 11:28:40
    Lua有很多封装.其中的利弊已经有不少介绍.只是提一下luaplus.本来期望值蛮高的.但后来发现文档质量不高.sample编译不过去....最后选择了LuaTinker.一个韩国人写的.2个文件.5个sample.简单清晰.赞一个.~
  • luatinker 的移植

    千次阅读 2010-06-23 15:39:00
    网上倒是对tolua++和luatinker有不少讨论,争论焦点是luatinker更傻瓜但因为用了不少c++写法不太好移植。去luatinker官网上看却写着for gcc 利用lua的makefile修改,尝试把luatinker插入到基础的lua库中# ma
  • LuaTinker的bug和缺陷

    千次阅读 2014-12-30 01:31:52
    LuaTinker的bug和缺陷 LuaTinker是一套还不错的C++代码和Lua代码的绑定库,作者是韩国人Kwon-il Lee,作者应该是参考了LuaBind后,为了简化和避免过重而实现的。其官网在http://gpgstudy.com/gpgiki/LuaTinker ,但...
  • luatinker 常用函数说明

    千次阅读 2014-07-21 16:16:17
    uatinker 提供的 lua与 C++ 函数的相关接口函数 ,这样便可以屏蔽底层函数,大大提升了了开发效率,但是luatinker是韩国人写的 所以函数的说明是韩文的,所以我把经常用到函数的功能写下了,方便新手使用 ...
  • LuaTinker的bug和缺陷 LuaTinker是一套还不错的C++代码和Lua代码的绑定库,作者是韩国人Kwon-il Lee,作者应该是参考了LuaBind后,为了简化和避免过重而实现的。其官网在http://gpgstudy.com/gpgiki/LuaTinker,但...
  • LuaTinker向Linux移植成功

    千次阅读 2007-06-06 17:14:00
    今天我怀着无比激动的心情写这篇博客。...看过LuaTinker的人都知道,LuaTinker短小精悍之处就在于模板的使用,但是其使用的却是VC中所特有的模板写法,许多写法都不能在Linux下编译通过,也就不能在Linux下使用
  • LuaTinker Lua C++封装

    2012-12-27 15:56:02
    Lua C++封装 这个不要资源分
  • 一、 ...-- C++类注册函数(LuaTinker) 的lua栈操作: -- lua栈内容(执行到pop语句) 栈地址 <--执行语句 space_name[name] = t1 -- (2b8) -- lua_rawset(L, -4); -- t1[__gc] = destroyer...
  • 一个实而不华的LuaTinker(1)

    千次阅读 2006-04-02 22:23:00
    LuaTinker的作者是Kwon-il Lee韩国人写的,最新的版本是0.2.C,这个C++ wrapper For Lua能够方便和快捷与C/C++通信,LuaTinker参考了luabind和luaplus的特征写的,虽然没有bindlua和luaplus这本强大和提供很多功能,...
  • 不是太好找的Lua Tinker库。韩国人写的,抛开民族争端问题,这套代码写得还是可以的,只是他用了VC的一些专用的模板技术,所以无法在GCC上编译通过,而且想改还不太容易。所以只考虑Windows的Lua工程的可以考虑使用...
  • LuaTinker_0.5b 源码

    2009-07-23 09:30:24
    非常简单的LUA绑定C++的.使用有一点类似luabind.
  • Lua有很多封装....最后选择了LuaTinker.一个韩国人写的.2个文件.5个sample.简单清晰.赞一个.~ 首先试验了几个基本功能.都没什么问题. 当时比较疑惑的几个问题是.在lua中可以使用指针么?可以使用c++中的数据
  • 一个实而不华的LuaTinker(2)附属代码

    千次阅读 2006-04-03 20:40:00
    // lua_tinker.h//// LuaTinker - Simple and light C++ wrapper for Lua.//// Copyright (c) 2005 Kwon-il Lee (zupet@hitel.net)// // please check Licence.txt file for licence and legal issues. #if !defin
  • luatinker 的一个计数 BUG

    千次阅读 2011-04-26 18:36:00
    最近用到luatinker 中的table 来进行对 c中容器到 lua中表的链接。之前触发式调用似乎还没啥问题,但当这种调用发生在每次tick的时候,内存开始受不了了。表现一般为会崩溃到无法从栈上面分配出新的区域  跟了一下...

空空如也

空空如也

1 2 3
收藏数 48
精华内容 19
热门标签
关键字:

luaTinker