2011-02-08 3 views
3

내가하고 싶은 일은 일부 개체를 반복하고 각 함수에 대해 함수를 호출하는 함수를 만드는 것입니다. C가 아닌 BlitzMax를 사용하고 있지만 루아의 C 함수의 전체 래퍼를 가지고 있기 때문에 그 점 이외에 다른 점이 있습니다. 루아는 lua_pushcfunction() 명령을 가지고 있습니다 만, lua_pushfunction() 명령은 어디에 있습니까? 이름이있는 함수를 호출하는 것은 매우 쉽지만 인수로 전달 된 함수는 어떻게 호출합니까?어떻게 Lua 함수를 C 함수에 전달하고 Lua 함수를 여러 번 실행합니까?

뭔가 같은 :

ForEach(PlanetList, function (planet) 
    if(planet.exists == true) then 
     Planet_Count = Planet_Count + 1 
    end 
end) 

보통 그냥 "lua_getglobal와 (L, 이름)"라고하고 스택에 잘 루아 기능을두고 있지만, 그것은 인수에서 어떻게받을 수 있나요? 실제로 다시 가서하고

편집 this question I found earlier에서 luaL_ref()를 사용했습니다. 내가 뭘하는지 luaL_ref() 스택의 상단에서 함수 값을 팝하고 임시 레지스터에 넣어, luaL_ref()에서 반환 된 값을 lua_rawgeti() 목록의 각 항목에 사용할 사용됩니다. 그런 다음 목록이 완성 된 후 해당 레지스터를 해제하기 위해 luaL_unref()을 사용했습니다.

+4

대답에 솔루션을 추출과 이용 약관을 읽고 동의를 바랍니다. –

답변

2

스택에 복제 할 기능이 있으면 lua_pushvalue을 사용하십시오.

업데이트 : 실제로 lua_pcall() 또는 lua_call()을 사용하여 함수를 호출하면 함수를 호출 할 때마다 lua_pushvalue()를 호출해야합니다.

+0

그게 효과가 있었지만 첫 번째 루프 만 통과했습니다. : S 나는 내 대답을 찾은 것 같아요, 나는 첫 번째 게시물을 업데이 트됩니다. – Galaxy613

4

나는 루아를 처음 접했을 때부터 같은 질문을했습니다. 내 의견으로는, 비록이 질문이 결코 닫히지 않을지라도 나는 하나를 쓸 것이라고 나는 만족스러운 대답이 없었습니다. 바라기를 이것은이 상황에서 다른 사람들을 도울 것입니다.

main.c를

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

/* this keeps our Lua reference to the Lua function */ 
int callback_reference = 0; 

/* this is called by Lua to register its function */ 
int lua_registerCallback(lua_State *L) { 

    /* store the reference to the Lua function in a variable to be used later */ 
    callback_reference = luaL_ref(L, LUA_REGISTRYINDEX); 

    return 0; 
} 

/* calls our Lua callback function and resets the callback reference */ 
void call_callback(lua_State *L) { 

    /* push the callback onto the stack using the Lua reference we */ 
    /* stored in the registry */ 
    lua_rawgeti(L, LUA_REGISTRYINDEX, callback_reference); 

    /* duplicate the value on the stack */ 
    /* NOTE: This is unnecessary, but it shows how you keep the */ 
    /* callback for later */ 
    lua_pushvalue(L, 1); 

    /* call the callback */ 
    /* NOTE: This is using the one we duplicated with lua_pushvalue */ 
    if (0 != lua_pcall(L, 0, 0, 0)) { 
    printf("Failed to call the callback!\n %s\n", lua_tostring(L, -1)); 
    return; 
    } 

    /* get a new reference to the Lua function and store it again */ 
    /* NOTE: This is only used in conjunction with the lua_pushvalue */ 
    /* above and can be removed if you remove that */ 
    callback_reference = luaL_ref(L, LUA_REGISTRYINDEX); 
} 

int main(void) { 

    /* set up Lua */ 
    lua_State *L = lua_open(); 
    luaL_openlibs(L); 

    /* register the lua_registerCallback function as */ 
    /* "RegisterCallback" so it can be called by Lua */ 
    lua_pushcfunction(L, lua_registerCallback); 
    lua_setglobal(L, "RegisterCallback"); 

    /* run our Lua file */ 
    if (0 != luaL_dofile(L, "callback.lua")) { 
    printf("Failed to load calback.lua!\n %s", 
     lua_tostring(L, -1)); 
    lua_close(L); 
    return 1; 
    } 

    /* call the callback */ 
    call_callback(L); 

    /* call the callback again if you want (because we restored */ 
    /* the Lua function reference) */ 
    call_callback(L); 

    /* remove the reference to the callback */ 
    /* NOTE: This is also unnecessary if you didn't re-add the */ 
    /* function to the registry */ 
    luaL_unref(L, LUA_REGISTRYINDEX, callback_reference); 

    /* uninitialize Lua */ 
    lua_close(L); 

    return 0; 
} 

callback.lua

function MyCallback() 
    print("Hello World!") 
end 

RegisterCallback(MyCallback) 
+1

내 테스트에서이 코드를 작동 시키려면'lua_pushvalue (L, 1);'을 제거해야한다. 그렇지 않으면'callback to callback! '에러가 발생할 수도있다. 12. – user1686407

+0

더 많은 테스트를 한 후에이 비동기 프로그램에서 작동하지 않는다. 왜냐하면 콜백을 호출 할 때 유효한'lua_State'를 얻을 방법이 없기 때문입니다. 또한'lua_State'를 저장하려고했지만 액세스 위반이 있습니다. – user1686407

관련 문제