C++调用LUA函数,可变参模板实现
来源:互联网 发布:js清空input内容 编辑:程序博客网 时间:2024/06/14 13:07
极其方便调用LUA函数,支持返回值方式:
调用示例:
luax_vcall("func_1", 12, 33, 4.0, "helloworld");
int result = luax_pvicall("utils.math.add", 20, 30, 100);
直接贴出代码:
/* powerful lua call, vardic template. */#ifndef _POWERFUL_LUA_CALL_HELPER_#define _POWERFUL_LUA_CALL_HELPER_/// helperinline bool luax_assume_func(lua_State* L, const char* func);/// FUNCTION TEMPLATE: luax_vcalltemplate<typename..._Args> inlinevoid luax_vcall(const char* func, const _Args&...args);template<typename _Result, typename..._Args> inline_Result luax_vxcall(const char* func, const _Args&...args);/// TEMPLATE luax_vxcall aliastemplate<typename..._Args> inlineint luax_vicall(const char* func, const _Args&...args);template<typename..._Args> inlinefloat luax_vfcall(const char* func, const _Args&...args);template<typename..._Args> inlinedouble luax_vdcall(const char* func, const _Args&...args);template<typename..._Args> inlinestd::string luax_vvcall(const char* func, const _Args&...args);/// FUNCTION TEMPLATE: luax_vpcalltemplate<typename..._Args> inlinevoid luax_pvcall(const char* func, const _Args&...args);template<typename _Result, typename..._Args> inline_Result luax_pvxcall(const char* func, const _Args&...args);/// TEMPLATE luax_pvxcall aliastemplate<typename..._Args> inlineint luax_pvicall(const char* func, const _Args&...args);template<typename..._Args> inlinefloat luax_pvfcall(const char* func, const _Args&...args);template<typename..._Args> inlinedouble luax_pvdcall(const char* func, const _Args&...args);template<typename..._Args> inlinestd::string luax_pvvcall(const char* func, const _Args&...args);/// arg push helperinlinevoid luax_vpusharg(lua_State* L, int& carg, int& narg){}inlinevoid luax_vpusharg(lua_State* L, int& carg, int& narg, int arg){ ++carg; if (lua_checkstack(L, 1)) lua_pushinteger(L, arg), ++narg;}inlinevoid luax_vpusharg(lua_State* L, int& carg, int& narg, float arg){ ++carg; if (lua_checkstack(L, 1)) lua_pushnumber(L, arg), ++narg;}inlinevoid luax_vpusharg(lua_State* L, int& carg, int& narg, double arg){ ++carg; if (lua_checkstack(L, 1)) lua_pushnumber(L, arg), ++narg;}inlinevoid luax_vpusharg(lua_State* L, int& carg, int& narg, const char* arg){ ++carg; if (lua_checkstack(L, 1)) lua_pushstring(L, arg), ++narg;}inlinevoid luax_vpusharg(lua_State* L, int& carg, int& narg, const std::string& arg){ ++carg; if (lua_checkstack(L, 1)) lua_pushlstring(L, arg.c_str(), arg.length()), ++narg;}inlinevoid luax_vpusharg(lua_State* L, int& carg, int& narg, void* arg){ ++carg; if (lua_checkstack(L, 1)) tolua_pushuserdata(L, arg), ++narg;}/// cocos2d-x object support#define LUAX_VCALL_ADD_CCOBJ_SUPPORT(type) \inline \void luax_vpusharg(lua_State* L, int& carg, int& narg, cocos2d::type* arg) \{ \ ++carg; \ if (lua_checkstack(L, 1)) \ object_to_luaval<cocos2d::type>(L, "cc." #type, arg),/*tolua_pushuserdata(L, arg),*/ ++narg; \}#define LUAX_VCALL_ADD_CCUI_SUPPORT(type) \inline \void luax_vpusharg(lua_State* L, int& carg, int& narg, type* arg) \{ \ ++carg; \ if (lua_checkstack(L, 1)) \ object_to_luaval<cocos2d::ui::type>(L, "ccui." #type, arg),/*tolua_pushuserdata(L, arg),*/ ++narg; \}LUAX_VCALL_ADD_CCOBJ_SUPPORT(Node)LUAX_VCALL_ADD_CCOBJ_SUPPORT(Scene)LUAX_VCALL_ADD_CCOBJ_SUPPORT(Layer)LUAX_VCALL_ADD_CCOBJ_SUPPORT(LayerColor)LUAX_VCALL_ADD_CCOBJ_SUPPORT(Sprite)template<typename _Ty, typename..._Args> inlinevoid luax_vpusharg(lua_State* L, int& carg, int& narg, _Ty arg1, const _Args&...args){ luax_vpusharg(L, carg, narg, arg1); luax_vpusharg(L, carg, narg, args...);}template<typename _Ty> inline_Ty luax_getretval(lua_State* L);template<> inlineint luax_getretval<int>(lua_State* L){ if (lua_isnumber(L, -1)){ return lua_tointeger(L, -1); } return 0;}template<> inlinefloat luax_getretval<float>(lua_State* L){ if (lua_isnumber(L, -1)){ return lua_tonumber(L, -1); } return 0;}template<> inlinedouble luax_getretval<double>(lua_State* L){ if (lua_isnumber(L, -1)){ return lua_tonumber(L, -1); } return 0;}template<> inlinestd::string luax_getretval<std::string>(lua_State* L){ if (lua_isstring(L, -1)){ return lua_tostring(L, -1); } return 0;}template<typename..._Args> inlinevoid luax_vcall(const char* func, const _Args&...args){ auto L = luax_get_L(); auto top = lua_gettop(L); // store stack int carg = 0, narg = 0; lua_getglobal(L, func); if (!lua_isfunction(L, -1)) { cocos2d::log("luax_vcall failed, function:%s not exist!", func); goto err_exit; } luax_vpusharg(L, carg, narg, args...); if (carg != narg) { cocos2d::log("luax_vcall failed, argument exception:carg:%d,narg:%d", carg, narg); goto err_exit; } if (lua_pcall(L, narg, 0, 0) != 0) { cocos2d::log("luax_vcall failed, func:%s", func); goto err_exit; } lua_settop(L, top); // resume stackerr_exit: lua_settop(L, top); // resume stack}inline bool luax_assume_func(lua_State* L, const char* func){ std::string source = func; const char* orig = source.c_str(); const char* name = orig; auto offst = 0; auto end = 0; end = source.find_first_of('.', offst); if (end == std::string::npos) { // assume _G.func lua_getglobal(L, name); if (lua_isfunction(L, -1)) return true; else return false; } // assume table source[end] = '\0'; lua_getglobal(L, name); if (!lua_istable(L, -1)) return false; offst = end + 1; // continue check sub table while ((end = source.find_first_of('.', offst)) != std::string::npos) { // assume table source[end] = '\0'; name = orig + offst; lua_getfield(L, -1, name); if (!lua_istable(L, -1)) { return false; } offst = end + 1; } // now assume function name = orig + offst; lua_getfield(L, -1, name); return !!lua_isfunction(L, -1);}template<typename _Result, typename..._Args> inline_Result luax_vxcall(const char* func, const _Args&...args){ auto L = luax_get_L(); auto top = lua_gettop(L); // store stack _Result result; int carg = 0, narg = 0; lua_getglobal(L, func); if (!lua_isfunction(L, -1)) { cocos2d::log("luax_vcall failed, function:%s not exist!", func); goto err_exit; } luax_vpusharg(L, carg, narg, args...); if (carg != narg) { cocos2d::log("luax_vcall failed, argument exception:carg:%d,narg:%d", carg, narg); goto err_exit; } if (lua_pcall(L, narg, 1, 0) != 0) { cocos2d::log("luax_vcall failed, lua_pcall failed"); goto err_exit; } result = luax_getretval<_Result>(L); lua_settop(L, top); // resume stack return std::move(result);err_exit: lua_settop(L, top); // resume stack return _Result();}// TEMPLATE luax_vxcall aliastemplate<typename..._Args> inlineint luax_vicall(const char* func, const _Args&...args){ return luax_vxcall<int>(func, args...);}template<typename..._Args> inlinefloat luax_vfcall(const char* func, const _Args&...args){ return luax_vxcall<float>(func, args...);}template<typename..._Args> inlinedouble luax_vdcall(const char* func, const _Args&...args){ return luax_vxcall<double>(func, args...);}template<typename..._Args> inlinestd::string luax_vvcall(const char* func, const _Args&...args){ return luax_vxcall<std::string>(func, args...);}// support any talbe prefixtemplate<typename..._Args> inlinevoid luax_pvcall(const char* func, const _Args&...args){ auto L = luax_get_L(); auto top = lua_gettop(L); // store stack int carg = 0, narg = 0; if (!luax_assume_func(L, func)) { cocos2d::log("luax_vcall failed, function:%s not exist!", func); goto err_exit; }do_call: luax_vpusharg(L, carg, narg, args...); if (carg != narg) { goto err_exit; } if (lua_pcall(L, narg, 0, 0) != 0) { goto err_exit; } lua_settop(L, top); // resume stackerr_exit: lua_settop(L, top); // resume stack}template<typename _Result, typename..._Args> inline_Result luax_pvxcall(const char* func, const _Args&...args){ auto L = luax_get_L(); auto top = lua_gettop(L); // store stack _Result result; int carg = 0, narg = 0; if (!luax_assume_func(L, func)) { cocos2d::log("luax_vcall failed, function:%s not exist!", func); goto err_exit; } luax_vpusharg(L, carg, narg, args...); if (carg != narg) { cocos2d::log("luax_vcall failed, argument exception:carg:%d,narg:%d", carg, narg); goto err_exit; } if (lua_pcall(L, narg, 1, 0) != 0) { cocos2d::log("luax_vcall failed, lua_pcall failed"); goto err_exit; } result = luax_getretval<_Result>(L); lua_settop(L, top); // resume stack return std::move(result);err_exit: lua_settop(L, top); // resume stack return _Result();}template<typename..._Args> inlineint luax_pvicall(const char* func, const _Args&...args){ return luax_pvxcall<int>(func, args...);}template<typename..._Args> inlinefloat luax_pvfcall(const char* func, const _Args&...args){ return luax_pvxcall<float>(func, args...);}template<typename..._Args> inlinedouble luax_pvdcall(const char* func, const _Args&...args){ return luax_pvxcall<double>(func, args...);}template<typename..._Args> inlinestd::string luax_pvvcall(const char* func, const _Args&...args){ return luax_pvxcall<std::string>(func, args...);}#endif /* powerful lua call, vardic template. */
0 0
- C++调用LUA函数,可变参模板实现
- Lua调用C函数的实现
- c++-可变参数模板函数
- [lua]C调用lua函数
- Lua调用C函数
- lua 调用c函数
- Lua调用C函数
- lua调用c函数
- Lua调用C函数
- lua调用C函数
- lua调用C函数
- lua调用C函数
- Lua调用C函数
- lua调用c函数
- lua调用C函数
- lua调用C函数
- Lua调用C函数
- lua 调用c函数
- java中的深克隆和浅克隆
- objective-c类初始化
- nginx 原理
- github 迁移google code 项目
- lighttpd 模块化
- C++调用LUA函数,可变参模板实现
- python: 目录操作
- Linux中断(interrupt)子系统之五:软件中断(softIRQ)
- Android中创建杀不死的APP进程(5.0以下)
- (一)线性表的链式存储结构
- 在C语言中的字符串(二)
- struts2、servlet中返回json数据格式
- Android中动态生成ListView及SimpleAdapter的使用
- SQLite数据库