神一般的狙击Lua的恶心操作(写个小小滴应用逻辑还要管出入栈这些恶心细节, 太二了,故哥决定干掉)

/********************************************************************

 author  :   Clark/陈泽丹

 created :   2013-5-8

 purpose :   反射辅助类

*********************************************************************/



#pragma once



//反射类型

struct RefClassType

{

	//获取类型

	virtual long GetType() = 0;

};



//获得反射类型

template< class Base, int TYPE_ID >

struct GetClassTypeEx: public Base

{

	//获取类型

	virtual long GetType(){ return TYPE_ID; }

};



//实例ID

struct RefClassID

{

	//获取类型

	virtual long GetID() = 0;

};



//获得类型ID

template< class Base >

struct GetClassIDEx: public Base

{

public:

	GetClassIDEx(const long _id):ID(_id){}

	//获取类型

	virtual long GetID(){ return ID; }



private:

	const long ID;

};


 

/********************************************************************

 author  :   Clark/陈泽丹

 created :   2013-5-8

 purpose :   LK_Typelist

*********************************************************************/

#pragma once





//-----------------------------------------------------------------------------------------------------------------------------

#define TL_1(T1) \

	LK_Typelist<T1, LK_NULL_TYPE>



#define TL_2(T1, T2) \

	LK_Typelist<T1, TL_1(T2) >



#define TL_3(T1, T2, T3) \

	LK_Typelist<T1, TL_2(T2, T3) >



#define TL_4(T1, T2, T3, T4) \

	LK_Typelist<T1, TL_3(T2, T3, T4) >



#define TL_5(T1, T2, T3, T4, T5) \

	LK_Typelist<T1, TL_4(T2, T3, T4, T5) >



#define TL_6(T1, T2, T3, T4, T5, T6) \

	LK_Typelist<T1, TL_5(T2, T3, T4, T5, T6) >



#define TL_7(T1, T2, T3, T4, T5, T6, T7) \

	LK_Typelist<T1, TL_6(T2, T3, T4, T5, T6, T7) >



#define TL_8(T1, T2, T3, T4, T5, T6, T7, T8) \

	LK_Typelist<T1, TL_7(T2, T3, T4, T5, T6, T7, T8) >







//-----------------------------------------------------------------------------------------------------------------------------

//参数队列

struct LK_NULL_TYPE{};

template <class T, class U>

struct LK_Typelist

{

	typedef T Head;

	typedef U Tail;

};



//获得参数队列长度

template< class TList >

struct LK_GetLength

{

	enum { Ret = 1 + LK_GetLength< TList::Tail >::Ret };

};

template<>

struct LK_GetLength<LK_NULL_TYPE>

{

	enum { Ret = 0 };

};



//获得类型

template< class TList, unsigned int index > 

struct LK_TypeAt;

template< class Head, class Tail >

struct LK_TypeAt< LK_Typelist<Head, Tail>, 0 >

{

	typedef Head Result;

};

template< class Head, class Tail, unsigned int i >

struct LK_TypeAt< LK_Typelist<Head, Tail>, i >

{

	typedef typename LK_TypeAt<Tail, i - 1>::Result Result;

};


 

/********************************************************************

 author  :   Clark/陈泽丹

 created :   2013-5-8

 purpose :   调用Lua函数

*********************************************************************/

#pragma once

#include "RefClassHelper.h"

#include <Windows.h>

#include <vector>

extern "C" 

{   

	#include <lua.h>  

	#include <lauxlib.h>    

	#include <lualib.h>    

} 



using namespace std;





// 数字类型

struct LuaNumber : public GetClassTypeEx<RefClassType, 1>

{ 

	LuaNumber(){ val = 0;}

	LuaNumber( double _val ){ val = _val; }

	void operator = (double _val){ val = _val; }

	double val;	

};



// 字符串类型

struct LuaString : public GetClassTypeEx<RefClassType, 2>

{ 

	LuaString(){ val[0] = 0; }

	LuaString( const char*_val ){ val[0] = 0; if( NULL != _val ) lstrcpyn(val, _val, sizeof(val)); }

	void operator = (const char *_val){ val[0] = 0; if( NULL != _val ) lstrcpyn(val, _val, sizeof(val)); }

	char val[1024];	

};





// 调用一个函数

bool CallLFun(lua_State *_L, const char* _lua_fun_name, vector< RefClassType* >* _in_pars = nullptr, vector< RefClassType* >* _out_pars = nullptr)

{

	//调用函数和参数

	lua_getglobal(_L, _lua_fun_name);

	int in_len = ( nullptr != _in_pars) ?  _in_pars->size() : 0;

	int out_len = ( nullptr != _out_pars) ?  _out_pars->size() : 0;

	if( nullptr != _in_pars)

	{

		in_len = _in_pars->size();

		for( int i=0; i<in_len; i++)

		{

			if( 1 == (*_in_pars)[i]->GetType() )

				lua_pushnumber(_L, ((LuaNumber*)(*_in_pars)[i])->val);

			else

				lua_pushstring(_L, ((LuaString*)(*_in_pars)[i])->val);

		}

	}

	if( 0 != lua_pcall(_L, in_len, out_len, 0) ){ goto FUN_ERROR; }

	//判读返回参数合法性

	if( out_len != lua_gettop(_L) ) { goto FUN_ERROR; }

	if( nullptr != _out_pars )

	{

		//获取参数

		for (int i = out_len - 1; i >= 0; i--)

		{

			if( 1 == (*_out_pars)[i]->GetType())

			{ 

				if (!lua_isnumber(_L, -1)){ goto FUN_ERROR;}

				*((LuaNumber*)(*_out_pars)[i]) = (double)lua_tonumber(_L, -1);

				lua_pop(_L, 1);

			}

			else

			{ 

				if (!lua_isstring(_L, -1)){ goto FUN_ERROR;}

				*((LuaString*)(*_out_pars)[i]) = (const char *)lua_tostring(_L, -1);

				lua_pop(_L, 1);

			}

		}

	}

	return true;



FUN_ERROR:

	//printf("Error in %s", _lua_fun_name);

	lua_settop(_L, 0);

	return false;

}





/*

vector<RefClassType*> in_pars;

vector<RefClassType*> out_pars;

LuaString val1("1");

in_pars.push_back(&val1);

LuaString val2("2");

in_pars.push_back(&val2);

LuaNumber oval1(0);

out_pars.push_back(&oval1);

LuaString oval2("");

out_pars.push_back(&oval2);

*/


 

/********************************************************************

 author  :   Clark/陈泽丹

 created :   2013-5-8

 purpose :   注册C函数进LUA并封装相关调用(原Lua开发包调用还是太麻烦了,哥果断呤唱“诸神黄昏”大招!)

*********************************************************************/

#pragma once

#include "LK_TypeList.h"

extern "C" 

{   

	#include <lua.h>  

	#include <lauxlib.h>    

	#include <lualib.h>    

} 









//-----------------------------------------------------------------------------------------------------------------------------

template< class _Ret, class _TypeList, int >

struct PopPar2CAction{};



//0参

template<class _Ret, class _TypeList>

struct PopPar2CAction<_Ret, _TypeList, 0>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun) { return fun(); }

};



//1参

#define INIT_LUA_VL_1(LTYP_LIST, I, _L) \

	LK_TypeAt< LTYP_LIST, I >::Result lua_stack_val_1 = NULL; \

	Lua_GetPar(lua_stack_val_1, _L, I+1); 

#define GET_LUA_VL_1() \

	lua_stack_val_1

template<class _Ret, class _TypeList >

struct PopPar2CAction<_Ret, _TypeList, 1>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun) { INIT_LUA_VL_1( _TypeList, 0, L ); return fun( GET_LUA_VL_1() ); }

};



//2参

#define INIT_LUA_VL_2(LTYP_LIST, I, _L) \

	LK_TypeAt< LTYP_LIST, I >::Result lua_stack_val_2 = NULL; \

	Lua_GetPar(lua_stack_val_2, _L, I+1); \

	INIT_LUA_VL_1(LTYP_LIST, I+1, _L)

#define GET_LUA_VL_2() \

	lua_stack_val_2, GET_LUA_VL_1()

template<class _Ret, class _TypeList >

struct PopPar2CAction<_Ret, _TypeList, 2>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun) 

	{ 

		INIT_LUA_VL_2( _TypeList, 0, L ); 

		return fun( GET_LUA_VL_2() ); 

	}

};



//3参

#define INIT_LUA_VL_3(LTYP_LIST, I, _L) \

	LK_TypeAt< LTYP_LIST, I >::Result lua_stack_val_3 = NULL; \

	Lua_GetPar(lua_stack_val_3, _L, I+1); \

	INIT_LUA_VL_2(LTYP_LIST, I+1, _L)

#define GET_LUA_VL_3() \

	lua_stack_val_3, GET_LUA_VL_2()

template<class _Ret, class _TypeList >

struct PopPar2CAction<_Ret, _TypeList, 3>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun) { INIT_LUA_VL_3( _TypeList, 0, L ); return fun( GET_LUA_VL_3() ); }

};



//4参

#define INIT_LUA_VL_4(LTYP_LIST, I, _L) \

	LK_TypeAt< LTYP_LIST, I >::Result lua_stack_val_4 = NULL; \

	Lua_GetPar(lua_stack_val_4, _L, I+1); \

	INIT_LUA_VL_3(LTYP_LIST, I+1, _L)

#define GET_LUA_VL_4() \

	lua_stack_val_4, GET_LUA_VL_3()

template<class _Ret, class _TypeList >

struct PopPar2CAction<_Ret, _TypeList, 4>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun) { INIT_LUA_VL_4( _TypeList, 0, L ); return fun( GET_LUA_VL_4() ); }

};



//5参

#define INIT_LUA_VL_5(LTYP_LIST, I, _L) \

	LK_TypeAt< LTYP_LIST, I >::Result lua_stack_val_5 = NULL; \

	Lua_GetPar(lua_stack_val_5, _L, I+1); \

	INIT_LUA_VL_4(LTYP_LIST, I+1, _L)

#define GET_LUA_VL_5() \

	lua_stack_val_5, GET_LUA_VL_4()

template<class _Ret, class _TypeList >

struct PopPar2CAction<_Ret, _TypeList, 5>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun) { INIT_LUA_VL_5( _TypeList, 0, L ); return fun( GET_LUA_VL_5() ); }

};



//6参

#define INIT_LUA_VL_6(LTYP_LIST, I, _L) \

	LK_TypeAt< LTYP_LIST, I >::Result lua_stack_val_6 = NULL; \

	Lua_GetPar(lua_stack_val_6, _L, I+1); \

	INIT_LUA_VL_5(LTYP_LIST, I+1, _L)

#define GET_LUA_VL_6() \

	lua_stack_val_6, GET_LUA_VL_5()

template<class _Ret, class _TypeList >

struct PopPar2CAction<_Ret, _TypeList, 6>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun) { INIT_LUA_VL_6( _TypeList, 0, L ); return fun( GET_LUA_VL_6() ); }

};



//7参

#define INIT_LUA_VL_7(LTYP_LIST, I, _L) \

	LK_TypeAt< LTYP_LIST, I >::Result lua_stack_val_7 = NULL; \

	Lua_GetPar(lua_stack_val_7, _L, I+1); \

	INIT_LUA_VL_6(LTYP_LIST, I+1, _L)

#define GET_LUA_VL_7() \

	lua_stack_val_7, GET_LUA_VL_6()

template<class _Ret, class _TypeList >

struct PopPar2CAction<_Ret, _TypeList, 7>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun) { INIT_LUA_VL_7( _TypeList, 0, L ); return fun( GET_LUA_VL_7() ); }

};



//8参

#define INIT_LUA_VL_8(LTYP_LIST, I, _L) \

	LK_TypeAt< LTYP_LIST, I >::Result lua_stack_val_8 = NULL; \

	Lua_GetPar(lua_stack_val_8, _L, I+1); \

	INIT_LUA_VL_7(LTYP_LIST, I+1, _L)

#define GET_LUA_VL_8() \

	lua_stack_val_8, GET_LUA_VL_7()

template<class _Ret, class _TypeList >

struct PopPar2CAction<_Ret, _TypeList, 8>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun) { INIT_LUA_VL_8( _TypeList, 0, L ); return fun( GET_LUA_VL_8() ); }

};



















//---------------------------------- 预判类型 ----------------------------------

template<class _Type>

struct Lua_IsType

{

	bool operator()(lua_State *L, int pos){ return false; }

};

template<>

struct Lua_IsType< double >

{

	bool operator()(lua_State *L, int pos){ return ( lua_isnumber(L, pos)?true:false ); }

};

template<>

struct Lua_IsType< long >

{

	bool operator()(lua_State *L, int pos){ return ( lua_isnumber(L, pos)?true:false ); }

};

template<>

struct Lua_IsType< int >

{

	bool operator()(lua_State *L, int pos){ return ( lua_isnumber(L, pos)?true:false ); }

};

template<>

struct Lua_IsType< char* >

{

	bool operator()(lua_State *L, int pos){ return ( lua_isstring(L, pos)?true:false ); }

};



//---------------------------------- 获得Lua传出来的参数 ----------------------------------

static bool Lua_GetPar(char*& _val, lua_State* _L, int _index)

{

	_val =  ((char*) lua_tostring(_L,_index));

	return true;

}

static bool Lua_GetPar(long& _val, lua_State* _L, int _index)

{

	_val =  ((long) lua_tonumber(_L,_index));

	return true;

}

static bool Lua_GetPar(bool& _val, lua_State* _L, int _index)

{

	_val =   lua_tonumber(_L, _index) != 0;

	return true;

}

static bool Lua_GetPar(int& _val, lua_State* _L, int _index)

{

	_val =  ((int) lua_tonumber(_L,_index));

	return true;

}

static bool Lua_GetPar(double& _val, lua_State* _L, int _index)

{

	_val =  ((int) lua_tonumber(_L,_index));

	return true;

}



//---------------------------------- 压入Lua的参数 ----------------------------------

template< class _Type >

static void Lua_PushPar(lua_State* _L, _Type _val)

{

	lua_pushnumber(_L, (lua_Number)_val);

}

static void Lua_PushPar(lua_State* _L, const char* _val)

{

	if (_val == NULL)

		lua_pushnil(_L);

	else

		lua_pushstring(_L,_val);

}



//---------------------------------- 检查压栈类型 ----------------------------------

template< class _TypeList >

class CheckLuaType

{

protected:

	template< class TList > 

	struct CheckAllType;

	template<>

	struct CheckAllType<LK_NULL_TYPE>

	{

		bool operator()(lua_State *L, int index)

		{ 

			return (lua_gettop(L)<abs(index) ? true:false);

		}

	};

	template <class T, class U>

	struct CheckAllType< LK_Typelist<T, U> >

	{

		bool operator()(lua_State *L, int index = 1)

		{

			if( !Lua_IsType<T>()(L, index) )

				return false; 

			return CheckAllType<U>()(L, index+1);

		}

	};

};



//---------------------------------- 弹出栈数据并装载进C函数和运行C函数 ----------------------------------

template< class _Ret, class _TypeList >

struct Par2CAction: public CheckLuaType<_TypeList>

{

	template< class _Fun >

	_Ret operator()(lua_State *L, _Fun fun)

	{

#ifdef _DEBUG

		//读取并判读参数

		if(lua_gettop(L) != LK_GetLength<_TypeList>::Ret )

		{

			lua_pushstring(L, "Incorrect argument number!");

			lua_error(L);

		}

		if(!CheckAllType< _TypeList >()(L))

		{

			lua_pushstring(L, "Incorrect argument!");

			lua_error(L);

		}

#endif

		PopPar2CAction<_Ret, _TypeList, LK_GetLength<_TypeList>::Ret> run;

		_Ret ret = run(L, fun);

		Lua_PushPar(L,ret);

		return ret;

	}

};

template< class _TypeList >

struct Par2CAction<void, _TypeList>: public CheckLuaType<_TypeList>

{

	template< class _Fun >

	void operator()(lua_State *L, _Fun fun)

	{

#ifdef _DEBUG

		//读取并判读参数

		if(lua_gettop(L) != LK_GetLength<_TypeList>::Ret )

		{

			lua_pushstring(L, "Incorrect argument number!");

			lua_error(L);

		}

		if( !CheckAllType< _TypeList >()(L))

		{

			lua_pushstring(L, "Incorrect argument!");

			lua_error(L);

		}

#endif

		PopPar2CAction<void, _TypeList, LK_GetLength<_TypeList>::Ret> run;

		run(L, fun);

		Lua_PushPar(L,0);

	}

};



//注册C函数到LUA里

template< int v, class _Fun, class _Stack >

class RegApiForLua

{

public:

	static void Register(lua_State *L, const char* _lua_fun_name, _Fun _c_fun)

	{ 

		mp_c_fun = &_c_fun; 

		lua_register( L, _lua_fun_name, (&RegApiForLua<v,_Fun,_Stack>::API) ); 

	}



private:

	static int API(lua_State *L)

	{

		m_par2caction(L, *mp_c_fun);

		return 1;

	}

	static _Stack	m_par2caction;

	static _Fun		*mp_c_fun;

};



template< int v, class _Fun, class _Stack >

_Stack RegApiForLua<v,_Fun,_Stack>::m_par2caction;

template< int v, class _Fun, class _Stack >

_Fun* RegApiForLua<v,_Fun,_Stack>::mp_c_fun = nullptr;



/*

RegApiForLua<0, decltype(test), Par2CAction<void, TL_1(int)> >::Register(L, "C_API", test);

RegApiForLua<1, decltype(test1), Par2CAction<int, TL_2(char*, int)> >::Register(L, "C_API1", test1);

*/


 

#include <iostream>

#include "RegCFun.h"

#include "CallLFun.h"



using namespace std;

#pragma comment(lib,"lua5.1.lib")



void test( int p1 )

{

	printf("test: %d\n", p1);

}



int test1( const char* p1, int p2 )

{

	printf("test1: %s, %d\n", p1, p2);

	return p2*2;

}





int main()

{

	lua_State *L = lua_open();

	luaL_openlibs(L);





	RegApiForLua<0, decltype(test), Par2CAction<void, TL_1(int)> >::Register(L, "C_API", test);

	RegApiForLua<1, decltype(test1), Par2CAction<int, TL_2(char*, int)> >::Register(L, "C_API1", test1);





	vector<RefClassType*> in_pars;

	vector<RefClassType*> out_pars;

	LuaString val1("C_par1");

	in_pars.push_back(&val1);

	LuaString val2("C_par2");

	in_pars.push_back(&val2);

	LuaNumber oval1;

	out_pars.push_back(&oval1);

	LuaString oval2;

	out_pars.push_back(&oval2);



	if (luaL_dofile(L, "test.lua"))

		nullptr;

	CallLFun(L, "LuaMain", &in_pars, &out_pars);

	lua_close(L);



	system("pause");

}










 

function LuaMain(p1, p2)

	print("p1", p1, "p2", p2)

	C_API(1000)

	local ret = C_API1("call C_API1", 5)

	print( ret )

	return ret, "LuaMain 的返回值"

end








你可能感兴趣的:(lua)