gpt4 book ai didi

lua-5.1 - 如何使用 C-API 在 Lua 5.1 中的表中创建表?

转载 作者:行者123 更新时间:2023-12-04 01:53:52 29 4
gpt4 key购买 nike

我需要在 Lua 中创建这样的结构 5.1 C-API,不在 Lua 5.2 及更高版本中

a = {["b"] = {["c"] = {["d"] = {["e"] = "GOOD"}}}}

print(a.b.c.d.e);

预期结果:好

感谢您的回答!

最佳答案

Lua C API 是基于堆栈的。这意味着大多数 C API 函数的行为不仅取决于给定的参数,还取决于 Lua 堆栈的内容(它是 lua_State* 变量的一部分,通常称为 L)。关于堆栈内容以及它如何影响堆栈元素,特定 API 函数期望什么,您必须在 Lua manual 中查找。 .

让我们开始创建一个表并将其分配给一个全局变量 a :

lua_newtable( L );
lua_setglobal( L, "a" );

这相当于 Lua 代码片段: a = {} .

lua_newtable() 的文档告诉我们该函数将新表推送到 Lua 堆栈的顶部。这很适合 lua_setglobal() ,它从栈顶弹出一个值并将其分配给给定名称的全局变量。所以两个函数结合起来(如上面的代码片段)是 平衡 在堆栈效应方面。堆栈平衡代码段的好处是您可以将它们插入到任何地方,并且组合后的代码仍然有效。 (一般规则是: 您可以用一系列语句替换单个语句,反之亦然,只要(组合)堆栈效果相同 。)例如:
lua_newtable( L );  /* ==> stack: ..., {} */
lua_pushnil( L ); /* ==> stack: ..., {}, nil */
lua_pop( L, 1 ); /* ==> stack: ..., {} */
lua_setglobal( L, "a" ); /* ==> stack: ... */

仍然会为全局变量 a 分配一个表因为 lua_pushnil( L );lua_pop( L, 1 );组合不更改 Lua 堆栈内容。代替这种无用的插入/弹出,我们将添加代码,在表被插入堆栈之后以及从堆栈中删除并分配给全局变量之前修改表。正如我所说,您可以在两个 Lua C API 函数之间的任何位置插入堆栈平衡的代码段,因此您只需确定堆栈包含您需要的所有元素的正确位置。

我们想用键 "b" 向表中添加一个字段和另一个表作为值。 Lua C API 函数是 lua_settable() (还有其他便利功能仅适用于某些键类型,例如 lua_setfield() ,但我们将在这里使用 lua_settable() )。 lua_settable()需要该表将键/值对存储在 Lua 堆栈的某个位置(这通常意味着您必须将堆栈索引作为参数传递),并将键和值作为最顶层的两个元素堆栈。 lua_settable() 会弹出键和值(但不是表)。 :
lua_newtable( L );  /* ==> stack: ..., {} */
lua_pushliteral( L, "b" ); /* ==> stack: ..., {}, "b" */
lua_newtable( L ); /* ==> stack: ..., {}, "b", {} */
lua_settable( L, -3 ); /* ==> stack: ..., {} */
lua_setglobal( L, "a" ); /* ==> stack: ... */

等效的 Lua 代码是 a = { b = {} }
通常,您并不真正关心 Lua 堆栈某个点下方的内容,这就是相对于堆栈顶部的索引(上面代码片段中的 -3)发挥作用的地方。 -3指的是键正下方的表 "b" (位于 -2 )和另一个表下方(位于 -1 的堆栈顶部)。

您可能已经看到这是怎么回事:现在我们要修改新表,因此我们在正确的位置添加堆栈平衡代码(在新表被插入堆栈之后)。我将跳过几个步骤并通过缩进指示我插入代码的位置:
lua_newtable( L );  /* ==> stack: ..., {} */
{
lua_pushliteral( L, "b" ); /* ==> stack: ..., {}, "b" */
lua_newtable( L ); /* ==> stack: ..., {}, "b", {} */
{
lua_pushliteral( L, "c" ); /* == stack: ..., {}, "b", {}, "c" */
lua_newtable( L ); /* ==> stack: ..., {}, "b", {}, "c", {} */
{
lua_pushliteral( L, "d" );
lua_newtable( L );
{
lua_pushliteral( L, "e" );
lua_pushliteral( L, "GOOD" );
lua_settable( L, -3 );
}
lua_settable( L, -3 );
}
lua_settable( L, -3 ); */ ==> stack: ..., {}, "b", {} */
}
lua_settable( L, -3 ); /* ==> stack: ..., {} */
}
lua_setglobal( L, "a" ); /* ==> stack: ... */

当您开发具有复杂堆栈操作的代码时,通常有助于在关键点打印出当前堆栈内容,或者至少检查堆栈上的元素数量(请参阅 lua_gettop() )是否符合您的预期。 Here是我用来做的。

关于lua-5.1 - 如何使用 C-API 在 Lua 5.1 中的表中创建表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37854422/

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