Two methods for C module to call back Lua function

Author: ani_di
All rights reserved for reprint http://blog.csdn.net/ani_di

Two methods for C module to call back Lua function

The interaction between Lua and C through virtual stack is simple and reliable. The disadvantage is that C will write a little more code when doing stack balancing. Today, I share the two methods of callback Lua function in module C. they are all fried rice. Don't spray them, great Xia.

1. C save function object

The C module can save the objects in Lua through the registry, take them out and call them when appropriate.

static int lua_callback = LUA_REFNIL;

static int setnotify(lua_State *L)
{
  lua_callback = luaL_ref(L, LUA_REGISTRYINDEX);
  return 0;
}

static int testnotify(lua_State *L)
{
  lua_rawgeti(L, LUA_REGISTRYINDEX, lua_callback);
  lua_call(L, 0, 0);
}

Lual [ref] takes the value at the top of the stack, places it in the specified tabel, and returns an index (which is visually the index of the array). Lua rawgeti takes out the previously saved function object and is called by Lua call.

function callback(  )
    print "Callback"
end

cb.setnotify(callback)
cb.testnotify()

2. C accesses Lua global environment

The second method is simpler. C calls functions in Lua directly, just like Lua calls C

static int testenv(lua_State *L)
{
  lua_getglobal(L, "defcallback");
  lua_call(L, 0, 0);
}

The disadvantage of this method is that if the C module is written independently, the method name is not very flexible. In this way, another layer will be encapsulated at Lua end to isolate the global environment.

3. Complete example

cb.c

#include <stdio.h>
#include <stdlib.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

static int lua_callback = LUA_REFNIL;

static int setnotify(lua_State *L)
{
  lua_callback = luaL_ref(L, LUA_REGISTRYINDEX);
  return 0;
}

static int testnotify(lua_State *L)
{
  lua_rawgeti(L, LUA_REGISTRYINDEX, lua_callback);
  lua_call(L, 0, 0);
}

static int testenv(lua_State *L)
{
  lua_getglobal(L, "defcallback");
  lua_call(L, 0, 0);
}

static const luaL_Reg cblib[] = {
  {"setnotify", setnotify},
  {"testnotify", testnotify},
  {"testenv", testenv},
  {NULL, NULL}
};

int luaopen_cb(lua_State *L)
{
  luaL_register(L, "cb", cblib);
  return 1;
}

test.lua

require("cb")

function callback(  )
  print "Callback"
end

function defcallback()
  print "Predef callback"
end

cb.setnotify(callback)
cb.testnotify()
print "Done"
cb.testenv()

Posted by kidsleep on Tue, 05 May 2020 13:42:32 -0700