使用下面方式可保存lua任何值,目前只实现fucntion的保存,且无参数。如果需要实现参数,可自己扩展:
可实现下面方式:
CFun( lua_fun ) -- ok CFun( function() print("Hello world") end ) --ok local xxx = function print("Hello world" ) end CFun( xxx ) --ok
lua_value.h
#ifndef __LUA_VALUE_H__ #define __LUA_VALUE_H__
extern "C" { #include "lualib.h" #include "lauxlib.h" }
class LuaFunction { public: LuaFunction(lua_State* L):m_L(L), m_ref(0){}; LuaFunction(lua_State* L, int index); ~LuaFunction();
void registerValue(); void push()const { lua_rawgeti(m_L,LUA_REGISTRYINDEX,m_ref); }
public: int Call(); bool Validate(); protected: lua_State* m_L; int m_ref; }; #endif
lua_value.cpp
#include "lua_value.h"
LuaFunction::LuaFunction( lua_State* L, int index ): m_L(L) { m_ref = lua_ref( m_L, index ); }
LuaFunction::~LuaFunction() { if (m_L && m_ref != 0) { luaL_unref(m_L,LUA_REGISTRYINDEX,m_ref); } }
bool LuaFunction::Validate() { if (!m_L) { return false; } push(); bool v = lua_isfunction(m_L,-1); lua_pop(m_L,1); return v; }
int LuaFunction::Call() { if (!Validate()) { return -1; } int status = -1; push(); if( lua_isfunction( m_L, -1 ) ) { status = lua_pcall(m_L, 0, 1,NULL); } lua_pop(m_L, 1); return status; }
void LuaFunction::registerValue() { m_ref = lua_ref( m_L, 2 ); //2为参数索引号,如果调用函数中包括其他参数,需要根据实际需要修改 }
lua测试代码:
valueTest=nil
for i=1,5,1 do function showidx()
print(i) return i; end if i== 3 then valueTest = LuaFunction:new() valueTest:registerValue(showidx) end end
valueTest:Call()
lua封装代码可用tolua实现,需要注意regisgerValue需要修改一下:
static int tolua_lua_value_LuaFunction_registerValue00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"LuaFunction",0,&tolua_err) ) goto tolua_lerror; else #endif { LuaFunction* self = (LuaFunction*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'registerValue'",NULL); #endif { self->registerValue(); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: tolua_error(tolua_S,"#ferror in function 'registerValue'.",&tolua_err); return 0; #endif }
|
请发表评论