Как передать функцию Lua в функцию C и выполнить функцию Lua несколько раз? - PullRequest
4 голосов
/ 08 февраля 2011

Что я хочу сделать, это создать функцию, которая будет перебирать некоторые объекты и вызывать функцию для каждой функции. Я использую BlitzMax, а не C, но это не имеет значения, потому что он имеет полную оболочку функций Си Lua. У Lua есть команда lua_pushcfunction (), но где эта команда lua_pushfunction ()? Вызывать функции с именем очень легко, но как вызвать функцию, переданную в качестве аргумента?

Что-то вроде:

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

Обычно вы просто говорите "lua_getglobal (L, name)", и она прекрасно помещает функцию lua в стек, но как вы получаете ее из аргумента?

EDIT

Я вернулся и фактически попытался использовать luaL_ref() из этот вопрос, который я нашел ранее . Я использую luaL_ref (), чтобы вытолкнуть значение функции из верхней части стека и поместить его во временный регистр. Я использовал значение, возвращаемое из luaL_ref(), чтобы использовать lua_rawgeti() для каждого элемента в списке , И затем использовал luaL_unref() после того, как список был закончен, чтобы освободить этот регистр.

Ответы [ 2 ]

5 голосов
/ 22 февраля 2014

У меня был тот же вопрос, так как я сам новичок в Lua.Поскольку, по моему мнению, не было удовлетворительного ответа, я решил написать его, даже если этот вопрос никогда не будет закрыт.Надеюсь, это поможет другим в этой ситуации.

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 )
3 голосов
/ 08 февраля 2011

Используйте lua_pushvalue, когда у вас есть функция в стеке для дублирования.

Обновление: вам нужно будет вызывать lua_pushvalue () каждый раз, когда вы хотите вызвать функцию как фактический вызов функции с lua_pcall() или lua_call () извлекают функцию из стека.

...