/*************************************** * **************************** Author: clark/Chen Zedan created: 2013-5-8 purpose: reflection-assisted class ************************************** * *****************************/# pragma once // reflection type struct refclasstype {// obtain the virtual long GetType () = 0 ;}; // obtain the reflection type template <class base, int type_id> struct getclasstypeex: public base {// obtain the virtual long GetType () {return type_id ;}}; // instance idstruct refclassid {// obtain type virtual long GETID () = 0 ;}; // obtain type idtemplate <class base> struct getclassidex: public base {public: getclassidex (const long _ ID): ID (_ id) {}// obtain the virtual long GETID () {return ID;} PRIVATE: const long ID ;};
/*************************************** * **************************** Author: clark/Chen Zedan created: 2013-5-8 purpose: lk_typelist *************************************** * *****************************/# pragma once/second # 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 // parameter queue struct lk_null_type {}; template <class t, class U> struct lk_typelist {typedef T head; typedef U tail ;}; // obtain the parameter queue length template <class tlist> struct lk_getlength {Enum {ret = 1 + lk_getlength <tlist:: tail >:: RET };}; template <> struct lk_getlength <lk_null_type >{enum {ret = 0 };}; // obtain the template type <class tlist, unsigned int index> struct lk_typeat; Template <class head, class tail> struct lk_typeat <lk_typelist
/*************************************** * **************************** Author: clark/Chen Zedan created: 2013-5-8 purpose: call the Lua function ************************************* * ******************************/# pragma once # include "refclasshelper. H "# include <windows. h >#include <vector> extern "C" {# include <Lua. h> # include <lauxlib. h> # include <lualib. h >}using namespace STD; // numeric type struct luanumber: Public GETC Lasstypeex <refclasstype, 1> {luanumber () {val = 0;} luanumber (double _ Val) {val = _ Val;} void operator = (double _ Val) {val = _ Val;} double Val ;}; // string type 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] ;}; // call a function bool calllfun (lua_state * _ L, const char * _ lua_fun_name, vector <refclasstype *> * _ in_pars = nullptr, vector <refclasstype *> * _ out_pars = nullptr) {// call functions and parameter 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); elselua_pushstring (_ L, (luastring *) (* _ in_pars) [I])-> Val);} If (0! = Lua_pcall (_ L, in_len, out_len, 0) {goto fun_error;} // interpret the validity of the returned parameter if (out_len! = Lua_gettop (_ L) {goto fun_error;} If (nullptr! = _ Out_pars) {// obtain the for (INT I = out_len-1; I> = 0; I --) {if (1 = (* _ out_pars) parameter) [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"); Evaluate (& val2); luanumber oval1 (0); out_pars.push_back (& oval1); luastring oval2 (""); out_pars.push_back (& oval2 ); */
/*************************************** * **************************** Author: clark/Chen Zedan created: Purpose !) **************************************** * ***************************/# Pragma once # include "lk_typelist.h" extern" C "{# include <Lua. h> # include <lauxlib. h> # include <lualib. h >}// define template <class _ ret, class _ typelist, int> struct poppar2caction {}; // 0 parameter template <class _ ret, Cl Ass _ typelist> struct poppar2caction <_ ret, _ typelist, 0> {template <class _ fun> _ RET operator () (lua_state * l, _ fun) {return fun () ;}}; // 1 parameter # 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_1template <class _ ret, class _ typelist> struct poppar2caction <_ ret, _ peltyist, 1> {Te Mplate <class _ fun> _ RET operator () (lua_state * l, _ 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> St Ruct poppar2caction <_ ret, _ typelist, 2> {template <class _ fun> _ RET operator () (lua_state * l, _ fun) {init_lua_vl_2 (_ typelist, 0, l); Return fun (get_lua_vl_2 () ;}}; // 3 parameter # 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); \ define (ltyp_list, I + 1, _ L) # define get_lua_vl_3 () \ lua_stack_val_3, limit () Template <class _ ret, class _ typelist> struct poppar2caction <_ ret, _ typelist, 3> {template <class _ fun> _ RET operator () (lua_state * l, _ fun) {init_lua_vl_3 (_ typelist, 0, L); Return fun (get_lua_vl_3 () ;}}; // 4 parameter # define init_lua__4 vl( 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) {init_lua_vl_4 (_ typelist, 0, L ); return fun (get_lua_vl_4 () ;};// 5 parameter # 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); \ In It_lua_vl_4 (ltyp_list, I + 1, _ L) # define evaluate () \ 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) {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); \ define (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) {init_lua_vl_6 (_ typelist, 0, L); Return fun (get_lua_vl_6 () ;}}; // 7 parameter # 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) {init_lua_vl_7 (_ typelist, 0, L ); return fun (get_lua_vl_7 () ;};// 8 # define init_lu A_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 ); \ define (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) {init_lua_vl_8 (_ typelist, 0, L); Return fun (Get_lua_vl_8 () ;}}; // ------------------------------------ pre-judgment 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) ;}}; // ---------------------------------- obtain the parameter 'prop static bool lua_getpar (char * & _ Val, lua_state * _ L, int _ index) passed by Lua) {_ 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;} // ---------------------------------- press the Lua parameter into template <class _ type> static void lua_pushpar (lua_state * _ L, _ type _ Val) {L Ua_pushnumber (_ L, (lua_number) _ Val);} static void lua_pushpar (lua_state * _ L, const char * _ Val) {If (_ Val = NULL) lua_pushnil (_ L); elselua_pushstring (_ L, _ Val);} // ------------------------------------ check the pressure stack type using template <class _ typelist> class checkluatype {protected: template <class tlist> struct checkalltype; Template <> struct checkalltype <lk_null_type> {bool operator () (lua_st Ate * 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 );}};}; // ---------------------------------- pop up the stack data and load it into the C function and run the C function -------------------------------- template <class _ ret, class _ typelist> struct par2caction: public checkluatype <_ typelist> {template <class _ fun> _ RET operator () (lua_state * l, _ fun) {# ifdef _ debug // read and interpret the parameter 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) ;}# endifpoppar2caction <_ 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) {# ifdef _ debug // read and interpret the parameter 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) ;}# endifpoppar2caction <void, _ typelist, lk_getlength <_ typelist >:: RET> run; run (L, fun); lua_pushpar (L, 0) ;}}; // register the C function to the 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 _ stackm_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 return value" End