gpt4 book ai didi

c - 尝试使用嵌套表在 Lua 中调用函数

转载 作者:太空狗 更新时间:2023-10-29 15:01:00 26 4
gpt4 key购买 nike

我正在尝试创建一个名为 Dfetch() 的 C 函数,它在 Lua 中注册为 fetch()。我正在寻找它是分层的,这样我就可以调用 dog.beagle.fetch() 作为 Lua 的函数。它只是有助于更好地组织代码。下面是我所拥有的,但它没有调用我的 C 函数。如果我只执行全局而不是子表,则会调用 C 函数。我是 Lua 的新手,所以我想我只是把表格设置错了。

void myregister(lua_State *L, const char *libname, const char *sublibname, const luaL_Reg *l) 
{
luaL_newmetatable(L, libname);
lua_newtable(L); luaL_setfuncs(L,l,0);
lua_pushvalue(L,-1);
if(sublibname != NULL)
{
lua_newtable(L);
lua_setfield(L, -2, sublibname);
}
lua_setglobal(L, libname);
}

luaL_Reg fidofuncModule[] = { {"fetch", Dfetch}, {NULL, NULL}};

在我的 main() 中,我调用了以下内容:

lua_State * execContext = luaL_newstate();
//adding lua basic library
luaL_openlibs(execContext);

myregister(execContext, "dog", "beagle", fidofuncModule);


strcpy(buff, "dog.beagle.fetch();");
errorcode = luaL_loadbuffer(execContext, buff, strlen(buff), "line");
errorcode = lua_pcall(execContext, 0, 0, 0);

if (errorcode)
{
printf("%s", lua_tostring(execContext, -1));
lua_pop(execContext, 1); /* pop error message from the stack */
}
//cleaning house
lua_close(execContext);

谢谢,蒂姆

最佳答案

问题

好的,让我们来看看这个函数和堆栈。

luaL_newmetatable(L, libname); 

好的,堆栈现在包含一个来自元表注册表的表:

-1: table<libname>{possibly empty}

下一步:

lua_newtable(L);

堆栈现在包含:

-1: table<new>{empty}
-2: table<libname>{possibly empty}

下一步:

luaL_setfuncs(L,l,0); 

不改变堆栈。但它确实在表中设置了一堆函数。

-1: table<new>{bunch of functions}
-2: table<libname>{possibly empty}

下一步:

lua_pushvalue(L,-1); 

这会将值复制到堆栈顶部。这是我们的表格,其中包含一系列功能:

-1: table<new>{bunch of functions}
-2: table<new>{bunch of functions}
-3: table<libname>{possibly empty}

下一步:

if(sublibname != NULL) 
{
lua_newtable(L);

这会在堆栈上创建一个空的新表:

-1: table<new2>
-2: table<new>{bunch of functions}
-3: table<new>{bunch of functions}
-4: table<libname>{possibly empty}

下一步:

    lua_setfield(L, -2, sublibname); 

这个函数,as stated in the documentation , 将值设置到给定表键名的表中。该值是堆栈顶部的值,但它放入的表是索引

所以你只是这样做了:

-1: table<new>{bunch of functions, sublibname=table<new2>}
-2: table<new>{bunch of functions, sublibname=table<new2>}
-3: table<libname>{possibly empty}

我很确定这不是您想要的。当我们继续时,我将了解如何解决这个问题。

下一步:

}

lua_setglobal(L, libname);

这会获取栈顶并将其粘贴到全局表中,然后将其从栈顶弹出。

所以堆栈现在看起来像这样:

-1: table<new>{bunch of functions, sublibname=table<new2>{empty}}
-2: table<libname>{possibly empty}

现在全局表有:

_G[libname] = table<new>{bunch of functions, sublibname=table<new2>{empty}}

因此,您不仅使堆栈失衡(压栈多于弹出栈),而且您没有得到您真正想要的东西。另外,您在注册表中的元表包含……什么都没有。

解决方案

所以让我们解决这个问题。让我们正确地做到这一点。

几乎所有关于您尝试做的事情都是错误的。首先,做子表的唯一原因是这样的代码可以工作:

myregister(execContext, "dog", "beagle", fidofuncModule);
myregister(execContext, "dog", "dane", danefuncModule);

这样,您就可以调用dog.beagledog.dane。那么,要做到这一点,myregister 必须检查全局表以查看是否已经有一个 dog 表。如果有,它需要将它的东西存储在那里,如果没有,它需要创建它。所以你的整个算法有点坏了。

此外,您可能希望 dog.beagledog.dane 都有自己的 fetch 函数。好吧,注册表只有一个地方可以放置 dog 表,所以如果您只使用 libname 进行 luaL_newmetatable 调用,它们就会被踩死在彼此的 table 上。

下面是的解决方法。我不知道这是否适用于您正在做的事情,但这就是我要做的。

首先,忘记整个 newmetatable 废话;我们始终基于新表格开展工作。所以我们将创建内表并在其上设置函数:

lua_newtable(L);
luaL_setfuncs(L,l,0);

所以堆栈看起来像:

-1: table<new>{bunch of functions}

下一步,如果我们没有子库名称,那么我们应该直接将其设置到libname下的全局变量中并返回:

if(!sublibname)
{
lua_setglobal(L, libname);
return;
}

这将从堆栈中弹出一个值并将其设置在该位置。

由于我们确实有一个分馆名,所以我们需要将这张表存储在主表中。如果 _G[libname] 中已经有一个表,那么我们将获取该表。否则,我们创建一个新表并将其粘贴到 _G[libname] 中。

lua_getglobal(L, libname);
if(lua_isnil(L, -1))
{
/*No table. Must create it and put it into the global*/
lua_newtable(L);
lua_pushvalue(L, -1); /*duplicate it on the stack*/
lua_setglobal(L, libname); /*pushes duplicate*/
}

此时,我们的堆栈包含:

-1: table<libname>{possibly empty}
-2: table<new>{bunch of functions}

然后我们将创建的表粘贴到该表中,使用 sublibname 作为字段:

lua_pushvalue(L, -2); /*duplicates our created table*/
lua_setfield(L, -2, sublibname);

现在堆栈包含:

-1: table<libname>{stuff, sublibname=table<new>{bunch of functions}}
-2: table<new>{bunch of functions}

因为表已经在全局表中(我们要么从那里得到它,要么在我们创建它时将它存储在那里),我们就完成了。所以清理堆栈:

lua_pop(L, 2); /*balance the stack. Remove our junk from it*/

关于c - 尝试使用嵌套表在 Lua 中调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13366287/

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