【问题标题】:Lua C API: Handling and storing additional argumentsLua C API:处理和存储附加参数
【发布时间】:2011-07-23 20:22:23
【问题描述】:

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

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

function CreateEntity( class, ... )  
    -- (choose a constructor function based on class)
    args = {...}
    -- (store args somewhere for whatever reason)
    TheConstructor( ... )  
end

但是如何使用 C Lua 函数做到这一点?

【问题讨论】:

  • 添加了 lua 标签,因为它实际上有一些追随者。
  • #lua 追随者万岁! ;)

标签: c++ c lua lua-api


【解决方案1】:

C 函数 lua_gettop 将返回传递给 C 函数的参数数量。您必须从堆栈中读取所有这些并将它们存储在 C 数据结构中,或者将它们放在 Lua 注册表中(请参阅 RegistryluaL_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;
}

【讨论】:

    【解决方案2】:
    args = {...}
    -- (store args somewhere for whatever reason)
    

    The arguments of the call are on the Lua stack,您可以随意使用它们:将它们放在您自己的结构中(std::vector&lt;boost::any&gt; 或类似的东西)或将单个参数存储在 the Lua registry 或创建一个带有参数的 Lua 表和而是将其存储在注册表中。什么更适合你?

    TheConstructor( ... )
    

    我相当确信这部分在 C++ 中不可能像在 Lua 中那样。 C++ 要求在编译时知道传递给函数的参数数量。

    尝试在 C++ 中执行这些操作会带来很大的不便。如果您告诉我们为什么希望您的 CreateEntity 函数位于 C++ 端而不是 Lua 端,也许会出现更好的解决方案。

    【讨论】:

    • 我认为你没有抓住重点。他不想编写一个以这种方式工作的 C++ 函数,他想使用 Lua C API 完成上述工作。
    • 也许我没有抓住重点......但是我仍然看不到如何使用运行时参数列表调用 C++ 方法(我认为 TheConstructor 是一个)而不诉诸 asm hack 或让构造函数了解 Lua。我很想在这件事上被证明是错误的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多