#1 Lua:
local test = Test();
#2 C:
//creating "lua's test" luaL_newmetatable(L, "someTable"); lua_userdata *userData = (lua_userdata *)lua_newuserdata(L, sizeof(lua_userdata)); luaL_getmetatable(L, "someTable"); lua_setmetatable(L, -2);
#3 Lua:
function test.newMethod() end
#4 C:
//this part is not executed from Lua //what i have to have here from #2 to call "test.newMethod" and how to call it? //if userdata would be on stack i guess i could: luaL_getmetafield (L, 1, "newMethod"); lua_call(L, 0, 0); //but because this part is not executed by Lua call its not on stack.
编辑:
将尝试解释伪代码更简单:
LUA:
local test = Object();
C:
int Object(){ ... somePointer = luaL_newmetatable(...); //how to get this "somePointer"? maybe luaL_ref? push ... }
Lua:制作新方法
function test.newMethod() ... end
在C中某些事件(比如说定时器)触发C方法
void triggeredCMethod(){ //here i need to call test.newMethod //if i would have here 'somePointer' and could push it to Lua stack i could find and call newMethod }
所以问题是:如何在C存储指针中指向一些Lua对象(希望我需要),通过该指针获取Lua对象并在其中调用方法
我假设您希望能够调用动态添加的函数.这段代码应该相对简单地解释一下.注意我没有做太多的错误检查并做了一些假设,不要复制粘贴这个作为解决方案.
typedef struct { int number; int reference; lua_State *L; } TestUserdata; static int m_newindex( lua_State *L ) { /* This is passed three values, first ( at -3 ) is the object, bring this to the front */ lua_getfenv( L, -3 ); /* Now bring the second arg forward, the key */ lua_pushvalue( L, -3 ); /* And the third arg, the value */ lua_pushvalue( L, -3 ); /* And we're done */ lua_rawset( L, -3 ); return 0; } static int m_tostring( lua_State *L ) { lua_pushstring( L, "TestUserdata" ); return 1; } static int callobject( lua_State *L ) { /* Grab the object passed, check it's the right type */ TestUserdata *data = luaL_checkudata( L, 1, "TestUserdata" ); /* Grab the function environment we gave it in createobject, and look in there for newmethod */ lua_getfenv( L, -1 ); lua_pushstring( L, "newmethod" ); lua_rawget( L, -2 ); /* Call the function */ lua_pushinteger( L, data->number ); lua_call( L, 1, 0 ); return 0; } static const struct luaL_reg userdata_m[] = { { "__newindex", m_newindex }, { "__tostring", m_tostring }, { NULL, NULL } }; int main (int argc, char *argv[]) { lua_State *L = luaL_newstate(); luaL_openlibs( L ); /* Let's create us a userdatum metatable, and fill it up with goodies */ luaL_newmetatable( L, "TestUserdata" ); /* Use luaL_register to fill up the metatable for us */ luaL_register( L, NULL, userdata_m ); lua_pop( L, 1 ); /* Clean up the stack, we won't need the metatable left here */ TestUserdata *data = lua_newuserdata( L, sizeof( TestUserdata ) ); lua_pushvalue( L, -1 ); /* Copy for luaL_ref */ int ref = luaL_ref( L, LUA_REGISTRYINDEX ); data->reference = ref; data->number = 42; data->L = L; /* Load the metatable from before and 'give' it to this userdatum */ luaL_getmetatable( L, "TestUserdata" ); lua_setmetatable( L, -2 ); /* Give this object an empty function environment */ lua_newtable( L ); lua_setfenv( L, -2 ); lua_setglobal( L, "test" ); luaL_dostring( L, "function test.newmethod( num ) print( num ) end" ); /* Now provided we have the object, we can call any method defined anywhere */ lua_rawgeti( data->L, LUA_REGISTRYINDEX, data->reference ); lua_getfenv( data->L, -1 ); lua_pushstring( data->L, "newmethod" ); lua_rawget( data->L, -2 ); lua_remove( data->L, -2 ); if( lua_isfunction( data->L, -1 ) == 1 ) { lua_pushinteger( data->L, data->number ); lua_pcall( data->L, 1, 0, 0 ); } lua_close( L ); return 0; }
检查一下,我认为这就是你所追求的.