2011-03-27 2 views
3

CreateEntity는 프로젝트에서 루아에 바인딩 된 C 함수입니다. 엔티티 클래스 이름 문자열을 첫 번째 인수로 사용하고 선택한 엔티티의 생성자에 전달해야하는 추가 인수를 여러 개 가져옵니다. 예를 들어 루아 C API : 추가 인수 처리 및 저장

, CreateEntity 정상적인 루아 기능이 있다면 나는 그것을 이런 식으로 할 수있는 :

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

을하지만 어떻게 내가 C 루아 기능이 작업을 수행 할 수 있습니까?

+0

실제로 추종자가 있기 때문에 lua 태그가 추가되었습니다. – BMitch

+6

#lua 추종자를위한 만세! ;) – sbk

+0

C 또는 C++에 있습니까? – Puppy

답변

1
args = {...} 
-- (store args somewhere for whatever reason) 

The arguments of the call are on the Lua stack 당신은 당신으로 그들과 함께 할 수있는하십시오 : 당신의 자신의 구조에 (같은 std::vector<boost::any> 또는 무언가)를 넣어 또는 the Lua registry에서 개별 인수를 저장하거나 인수 및 저장과 루아 테이블을 만드는 것이 대신 레지스트리에 저장하십시오. 뭐가 더 어울리는거야?

TheConstructor(...) 

저는이 부분이 C++에서는 Lua에서 가능하지 않다고 확신합니다. C++에서는 컴파일 타임에 함수에 전달할 매개 변수의 수를 알아야합니다.

C++에서 이러한 작업을 시도하고 수행하는 것이 큰 불편입니다. 어쩌면 당신이 CreateEntity 함수가 루아 대신에 C++ 측에 있기를 원하는 이유를 우리에게 말해 준다면 더 좋은 해결책이 올 것입니다.

+0

당신이 그 요점을 놓치고 있다고 생각합니다. 그는 이런 방식으로 작동하는 C++ 함수를 작성하고 싶지는 않지만 위의 코드는 Lua C API를 사용하여 수행하려고합니다. – Puppy

+0

어쩌면 나는 요점을 놓치고있다. 그러나 나는 asm 해킹이나 생성자가 루아를 인식하지 않고서도 run-time 인수 목록으로 C++ 메소드 ('TheConstructor'가 하나이다)를 호출 할 수있는 방법을 여전히 볼 수 없다. . 나는 이것에 대해 틀린 것으로 입증되고 싶다. – sbk

4

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; 
}