lua筆記 — 一個C++調用lua函數的類的實現

來源:互聯網
上載者:User

這個類基本上是從LuaPlus那裡弄來的,為什麼不支援用LuaPlus,因為那東西我實在不知道怎麼編譯,能編譯通過的版本的舊版本的了,而且之前的版本有BUG的存在,使用起來有陰影,不想用了,還是自己寫個比較靠譜。

因為感覺LuaPlus那個LuaFunction有點不好用,所以進行了一些改造。自己認為目前自己封裝的這個還是比較好用的。

 

namespace Lua_Wrapper{struct LuaNil{};inline void Push(lua_State* L, bool value){  lua_pushboolean(L, value);  }inline void Push(lua_State* L, char value){  lua_pushnumber(L, value);  }inline void Push(lua_State* L, unsigned char value){  lua_pushnumber(L, value);  }inline void Push(lua_State* L, short value){  lua_pushnumber(L, value);  }inline void Push(lua_State* L, unsigned short value){  lua_pushnumber(L, value);  }inline void Push(lua_State* L, int value){  lua_pushnumber(L, value);  }inline void Push(lua_State* L, unsigned int value){  lua_pushnumber(L, value);  }inline void Push(lua_State* L, long value){  lua_pushnumber(L, value);  }inline void Push(lua_State* L, unsigned long value){  lua_pushnumber(L, value);  }inline void Push(lua_State* L, double value){  lua_pushnumber(L, (lua_Number)value);  }inline void Push(lua_State* L, float value){  lua_pushnumber(L, (lua_Number)value);  }inline void Push(lua_State* L, const char* value){  lua_pushstring(L, value);  }inline void Push(lua_State* L, const LuaNil&){  lua_pushnil(L);  }inline void Push(lua_State* L, lua_CFunction value){  lua_pushcclosure(L, value, 0);  }inline void Push(lua_State* L, const void* value){  lua_pushlightuserdata(L, (void*)value);  }struct Get{lua_State* L;int idx;Get(lua_State* L,int index=-1):L(L),idx(index){}operator bool(){assert(lua_isboolean(L,idx));return lua_toboolean(L, idx) != 0;}operator char(){assert(lua_isnumber(L,idx));return static_cast<char>(lua_tonumber(L, idx));}operator unsigned char(){assert(lua_isnumber(L,idx));return static_cast<unsigned char>(lua_tonumber(L, idx));}operator short(){assert(lua_isnumber(L,idx));return static_cast<short>(lua_tonumber(L, idx));}operator unsigned short(){assert(lua_isnumber(L,idx));return static_cast<unsigned short>(lua_tonumber(L, idx));}operator int(){assert(lua_isnumber(L,idx));return static_cast<int>(lua_tonumber(L, idx));}operator unsigned int(){assert(lua_isnumber(L,idx));return static_cast<unsigned int>(lua_tonumber(L, idx));}operator long(){assert(lua_isnumber(L,idx));return static_cast<long>(lua_tonumber(L, idx));}operator unsigned long(){assert(lua_isnumber(L,idx));return static_cast<unsigned long>(lua_tonumber(L, idx));}operator double(){assert(lua_isnumber(L,idx));return static_cast<double>(lua_tonumber(L, idx));}operator float(){assert(lua_isnumber(L,idx));return static_cast<float>(lua_tonumber(L, idx));}operator const char*(){assert(lua_isstring(L,idx));return static_cast<const char*>(lua_tostring(L, idx));}operator lua_CFunction(){assert(lua_iscfunction(L,idx));return static_cast<lua_CFunction>(lua_tocfunction(L, idx));}operator void*(){assert(lua_islightuserdata(L,idx));return static_cast<void*>(lua_touserdata(L, idx));}};}class luaautoblock{public:luaautoblock(lua_State* L) :  L(L), m_stackTop(lua_gettop(L)){}  ~luaautoblock(){lua_settop(L, m_stackTop);}private:luaautoblock(const luaautoblock& src);// Not implementedconst luaautoblock& operator=(const luaautoblock& src);// Not implementedlua_State* L;int m_stackTop;};struct CallLuaFunction{lua_State* L;luaautoblock autoblock;CallLuaFunction(lua_State* L, const char* fnName):L(L),autoblock(L){lua_getglobal(L,fnName);if(lua_pcall(L,0,1,0)){logluaerror(L);}}template<class T1>CallLuaFunction(lua_State* L, const char* fnName, T1 t1):L(L),autoblock(L){lua_getglobal(L,fnName);Lua_Wrapper::Push(L,t1);if(lua_pcall(L,1,1,0)){logluaerror(L);}}template<class T1,class T2>CallLuaFunction(lua_State* L, const char* fnName, T1 t1, T2 t2):L(L),autoblock(L){lua_getglobal(L,fnName);Lua_Wrapper::Push(L,t1);Lua_Wrapper::Push(L,t2);if(lua_pcall(L,2,1,0)){logluaerror(L);}}template<class T1,class T2,class T3>CallLuaFunction(lua_State* L, const char* fnName, T1 t1, T2 t2, T3 t3):L(L),autoblock(L){lua_getglobal(L,fnName);Lua_Wrapper::Push(L,t1);Lua_Wrapper::Push(L,t2);Lua_Wrapper::Push(L,t3);if(lua_pcall(L,3,1,0)){logluaerror(L);}}template<class T1,class T2,class T3,class T4>CallLuaFunction(lua_State* L, const char* fnName, T1 t1, T2 t2, T3 t3, T4 t4):L(L),autoblock(L){lua_getglobal(L,fnName);Lua_Wrapper::Push(L,t1);Lua_Wrapper::Push(L,t2);Lua_Wrapper::Push(L,t3);Lua_Wrapper::Push(L,t4);if(lua_pcall(L,4,1,0)){logluaerror(L);}}template<class T1,class T2,class T3,class T4,class T5>CallLuaFunction(lua_State* L, const char* fnName, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5):L(L),autoblock(L){lua_getglobal(L,fnName);Lua_Wrapper::Push(L,t1);Lua_Wrapper::Push(L,t2);Lua_Wrapper::Push(L,t3);Lua_Wrapper::Push(L,t4);Lua_Wrapper::Push(L,t5);if(lua_pcall(L,5,1,0)){logluaerror(L);}}template<class T1,class T2,class T3,class T4,class T5,class T6>CallLuaFunction(lua_State* L, const char* fnName, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5,T6 t6):L(L),autoblock(L){lua_getglobal(L,fnName);Lua_Wrapper::Push(L,t1);Lua_Wrapper::Push(L,t2);Lua_Wrapper::Push(L,t3);Lua_Wrapper::Push(L,t4);Lua_Wrapper::Push(L,t5);Lua_Wrapper::Push(L,t6);if(lua_pcall(L,6,1,0)){logluaerror(L);}}template<class T1,class T2,class T3,class T4,class T5,class T6,class T7>CallLuaFunction(lua_State* L, const char* fnName, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7):L(L),autoblock(L){lua_getglobal(L,fnName);Lua_Wrapper::Push(L,t1);Lua_Wrapper::Push(L,t2);Lua_Wrapper::Push(L,t3);Lua_Wrapper::Push(L,t4);Lua_Wrapper::Push(L,t5);Lua_Wrapper::Push(L,t6);Lua_Wrapper::Push(L,t7);if(lua_pcall(L,7,1,0)){logluaerror(L);}}template<class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>CallLuaFunction(lua_State* L, const char* fnName, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8):L(L),autoblock(L){lua_getglobal(L,fnName);Lua_Wrapper::Push(L,t1);Lua_Wrapper::Push(L,t2);Lua_Wrapper::Push(L,t3);Lua_Wrapper::Push(L,t4);Lua_Wrapper::Push(L,t5);Lua_Wrapper::Push(L,t6);Lua_Wrapper::Push(L,t7);Lua_Wrapper::Push(L,t8);if(lua_pcall(L,8,1,0)){logluaerror(L);}}template<class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>CallLuaFunction(lua_State* L, const char* fnName, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9):L(L),autoblock(L){lua_getglobal(L,fnName);Lua_Wrapper::Push(L,t1);Lua_Wrapper::Push(L,t2);Lua_Wrapper::Push(L,t3);Lua_Wrapper::Push(L,t4);Lua_Wrapper::Push(L,t5);Lua_Wrapper::Push(L,t6);Lua_Wrapper::Push(L,t7);Lua_Wrapper::Push(L,t8);Lua_Wrapper::Push(L,t9);if(lua_pcall(L,9,1,0)){logluaerror(L);}}template<class RT>operator RT(){return Lua_Wrapper::Get(L);}};

使用方法:

 

 

luaL_dostring(L,"function test(...) print(...) return 'ok' end");const char* ret = CallLuaFunction(L,"test","a","b",3,&a,5,"666",7,"888",998);//調用lua函數printf("ret:%s\n",ret);

看起來就像是個函數,不過目前有問題就是調用過多可能會導致lua滿棧,我懷疑以前遇到的luaplus的BUG是不是就是這個,如果只是局部變數就沒有問題,會自動清理掉,這個問題感覺不好處理,目前能想到的辦法就是跟luaplus一樣弄個void的版本

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.