3

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 関数でこれを行うにはどうすればよいでしょうか?

4

2 に答える 2

4

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-28T13:53:06.753 に答える
1
args = {...}
-- (store args somewhere for whatever reason)

呼び出しの引数は Lua スタック上にあり、好きなように扱うことができます: 独自の構造 (std::vector<boost::any>またはそのようなもの) に配置するか、個々の引数をLua レジストリに格納するか、引数を使用して Lua テーブルを作成します。代わりにレジストリに保存します。どれが似合う?

TheConstructor( ... )

この部分は、Lua のように C++ では不可能であると確信しています。C++ では、関数に渡すパラメーターの数がコンパイル時に認識される必要があります。

これらのことを C++ で試して実行するのは非常に不便です。CreateEntity 関数を Lua ではなく C++ 側にする理由を教えていただければ、より良い解決策が得られるかもしれません。

于 2011-03-27T14:36:11.377 に答える