• 神一般的狙击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
    
    
    
    


  • 相关阅读:
    Send EMail from your .NET Application using your GMail Account
    ObjectContext 是开发人员在查询、添加和删除其实体实例以及将新状态保存回数据库时用到的主要构造
    AjaxPro使用说明
    .NET Framework 类库
    sysobjects syscolumns和SysTypes笔记
    javascript 懒加载技术(lazyload)简单实现
    WEB前端开发笔试题2
    css方框模型(盒模型Box Model)
    让IE支持CSS3选择器的方法(利用JS)
    让IE6/IE7/IE8浏览器支持CSS3属性
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3085946.html
Copyright © 2020-2023  润新知