LuaTinker

来源:互联网 发布:迁移阿里云rds到aws 编辑:程序博客网 时间:2024/05/21 15:45

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的成员变量_testprint(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;}  
0 0