Skip to content

Instantly share code, notes, and snippets.

@jamespascoe
Created July 7, 2020 16:16
Show Gist options
  • Save jamespascoe/523a5cf4114a1230b4d8a386bb8cd8ba to your computer and use it in GitHub Desktop.
Save jamespascoe/523a5cf4114a1230b4d8a386bb8cd8ba to your computer and use it in GitHub Desktop.
SWIG Callback Example for mapping std::function (C++) to Lua functions
#include <iostream>
#include "lua5.3/lua.hpp"
#include "callback.hpp"
extern "C" {
int luaopen_Callback(lua_State* L);
}
Example::Example(Example::Callback const& callback)
{
std::cout << "Calling Lua callback" << std::endl;
if (callback) callback();
}
int main([[maybe_unused]] int argc, char ** argv)
{
// Create a new lua state
lua_State *L = luaL_newstate();
// Open all libraries
luaL_openlibs(L);
luaopen_Callback(L);
// Load and run the Lua file
luaL_loadfile(L, argv[1]);
lua_pcall(L, 0, 1, 0);
lua_close(L);
}
#include <functional>
class Example {
public:
using Callback = std::function<void(void)>;
Example(Example::Callback const& callback = {});
};
%module Callback
%include <lua_fnptr.i>
%{
#include "callback.hpp"
%}
%typemap(typecheck) Example::Callback & {
$1 = lua_isfunction(L, $input);
}
%typemap(in) Example::Callback & (Example::Callback temp) {
// Create a reference to the Lua callback
SWIGLUA_REF fn;
swiglua_ref_set(&fn, L, $input);
temp = [&fn]() {
swiglua_ref_get(&fn);
lua_pcall(fn.L, 0, 0, 0);
};
$1 = &temp;
}
%include "callback.hpp"
local function callback()
print("Lua callback called")
end
Callback.Example(callback)
@jamespascoe
Copy link
Author

jamespascoe commented Jul 7, 2020

This has been tested using SWIG 4.0, Clang++ 9 and Lua 5.3.5 on Linux Mint 19. Example compilation lines are:

swig -Wall -Werror -Wallkw -c++ -lua callback.i
clang++-9 -std=c++17 -I /usr/include/lua5.3 callback.cpp callback_wrap.cxx -llua5.3 -o callback

Then run with:

./callback callback.lua 
Calling Lua callback
Lua callback called

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment