gpt4 book ai didi

c - 保存对 Lua 用户数据的引用

转载 作者:太空宇宙 更新时间:2023-11-04 01:15:42 25 4
gpt4 key购买 nike

#1 路亚:

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 路亚:

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.

编辑:

将尝试用伪代码解释得更简单:

路亚:

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;
}

检查一下,我认为这就是您想要的。

关于c - 保存对 Lua 用户数据的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1646497/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com