zoukankan      html  css  js  c++  java
  • lua笔记 一个C++调用lua函数的类的实现

    这个类基本上是从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 implemented
    	const luaautoblock& operator=(const luaautoblock& src);	// Not implemented
    
    	lua_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的版本

  • 相关阅读:
    Colmap在centos7下的编译
    图像搜索三-局部特征SIFT
    docker的基本概念
    图像搜索(二)-全局特征
    图像搜索(一)-好特征
    Android图片生成器
    Android Studio Prower Save Mode问题
    finished with non-zero exit value 1
    安装pod程序
    小米刷入Recovery
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3074090.html
Copyright © 2011-2022 走看看