Success! I have a solution that works:
The idea of what I did, is to wrap the callback with "directors", and "return" the Go function pointer back to Go, so it could be run in that context.
The solution below is not perfect, but it's close enough for my needs, and it's pretty easy to make it perfect from here on.
The C++ file:
class Callback {
public:
virtual void Run(void(*f)(void)) = 0;
virtual ~Callback() {}
};
Callback* GlobalCallback;
void TestFunc(void(*f)(void)) {
GlobalCallback->Run(f);
}
I've added a class Callback, which will be "extended" in Go (using Swig directors), and I'll have a global instance of this extended class. Thus, calling Run() of that instance, would call a Go function which will receive a function pointer.
Please notice that my TestFunc now instead of just running f(), runs it through the GlobalCallback. It's easy to fix by adding another function that returns a pointer to a function that runs GlobalCallback->Run(f), and pass this pointer to the function instead of *f.
My Swig file:
%{
#include "test.h"
%}
%module(directors="1") Callback
%feature("director");
%typemap(gotype) FUNC* "func()"
%typemap(in) FUNC* {
$1 = (void(*)(void))$input;
}
%apply FUNC* { void(*)(void) };
%include "test.h"
%insert(go_wrapper) %{
type go_callback struct { }
func (c* go_callback) Run(f func()) {
f()
}
func init() {
SetGlobalCallback(NewDirectorCallback(&go_callback{}))
}
%}
Notice that i've added an init() function that sets the GlobalCallback with a Go function that runs the pointer.
That's it, the Go code is as it was, and it works :)