Lua C API:处理和存储额外的参数

CreateEntity 是我在项目中制成 Lua 绑定的 C 函数。它将实体类名字符串作为第一个参数,并将任意数量的附加参数传递给所选实体的构造函数。

例如,如果 CreateEntity 是一个普通的 Lua 函数,我可以这样做:

function CreateEntity( class, ... )
    -- (根据类别选择构造函数)
    args = {...}
    -- (出于某种原因将 args 储存在某个地方)
    TheConstructor( ... )
end

但我该如何用 C Lua 函数完成这个过程?

原文链接 https://stackoverflow.com/questions/5448654

点赞
stackoverflow用户169828
stackoverflow用户169828
args = {...}
--(将 args 存储在某个地方,出于某种原因)

调用参数在 Lua 栈上,您可以根据需要对其进行处理:将它们放入自己的结构体中(例如 std::vector<boost::any>),或将单个参数存储在Lua 注册表中,或创建一个带有参数的 Lua 表,并将其存储在注册表中。哪个适合您的需求?

TheConstructor( ... )

我相当确信在 C++ 中以 Lua 的方式来使用这个部分是不可能的。C++ 要求在编译时知道传递给函数的参数数量。

尝试在 C++ 中实现这些功能是一项很大的不便。也许,如果您告诉我们为什么要将您的 CreateEntity 函数放在 C++ 方面而不是 Lua 方面,可能会有更好的解决方案。

2011-03-27 14:36:11
stackoverflow用户1491
stackoverflow用户1491

C 函数 lua_gettop 将返回传递给您的 C 函数的参数数量。您必须从堆栈中读取它们并将它们存储在 C 数据结构中,或将它们放在 Lua 注册表中(参见注册表luaL_ref),并为以后使用存储引用。下面的示例程序使用了注册表方法。

#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
#include <stdio.h>
#include <stdlib.h>

/* this function prints the name and extra variables as a demonstration */
static void
TheConstructor(lua_State *L, const char *name, int *registry, int n)
{
    int i;

    puts(name);

    for (i = 0; i < n; ++i) {
        lua_rawgeti(L, LUA_REGISTRYINDEX, registry[i]);
        puts(lua_tostring(L, -1));
    }

    free(registry);
}

static int
CreateEntity(lua_State *L)
{
    const char *NAME = luaL_checkstring(L, 1);
    int *registry;
    int i, n;

    /* remove the name parameter from the stack */
    lua_remove(L, 1);

    /* check how many arguments are left */
    n = lua_gettop(L);

    /* create an array of registry entries */
    registry = calloc(n, sizeof (int));
    for (i = n; i > 0; --i)
        registry[i-1] = luaL_ref(L, LUA_REGISTRYINDEX);

    TheContructor(L, NAME, registry, n);

    return 0;
}

int
main(int argc, char **argv[])
{
    const char TEST_CHUNK[] =
        "CreateEntity('foo', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)";
    lua_State *L;

    L = luaL_newstate();
    lua_register(L, "CreateEntity", CreateEntity);
    luaL_dostring(L, TEST_CHUNK);
    lua_close(L);

    return EXIT_SUCCESS;
}
2011-03-28 13:53:06