c保存lua函数
使用下面方式可保存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
endvalueTest: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
}