One way to setup a callback function to be passed in to a parameter to a DLL function is to use CGO...
package main
/*
#cgo LDFLAGS: -L${SRCDIR} -lsomelib
#include "somelib.h"
extern void CallbackString(char* s);
*/
import "C"
import (
"unsafe"
"fmt"
)
//export CallbackString
func CallbackString(s *C.char) {
gostr := C.GoString(s) // convert to golang string
fmt.Println("Got string from dll (or dso): ", gostr)
}
func Example() {
// setup a callback by calling a function in
// the DLL requiring callback param
C.SomeDLLFunc(x,y,
(C.TCallbackString)(unsafe.Pointer(C.CallbackString)),
other,
params)
}
func main() {
Example()
}
where the callback is defined as
typedef void (*TCallbackString)(char*);
But I am wondering if there is a way to avoid using CGO and just pass the go function in as a parameter without requiring needless C code bindings.. i.e.
C.SomeDLLFunc(x,y,
CallbackString, // how to send the go function in as a callback?
other,
params)
Does it always require writing C bindings or whatever you call them, C links to the go code, C exports/externs, in order to send a callback as a param?
There is no way to just make a go function a callback without making it C-ish first?
C.SomeDLLFunc(x,y,
WhatCastIsNeeded(CallbackString), // regular go function as a callback?
other,
params)
There is some way to avoid the cast and simplify callback code.
// cgo.h in dll
typedef void (*Callback)(int kind,void* arg);
void SetCallback(Callback func);
// cgo.c in dll
Callback Gfunc;
void SetCallback(Callback func){
Gfunc=func;
}
// cgocb.h in go project
void InitCallback();
extern void goCallbackFunction(int kind,void* arg);
// cgocb.c in go project
void InitCallback(){
SetCallback(goCallbackFunction);
}
// cgocb.go in go project
// export goCallbackFunction
func goCallbackFunction(kind C.int,arg unsafe.Pointer){
switch kind{
case C.AKind:
arg:=(*C.AKind)(arg)
AkindCallback(arg)
}
}
C.InitCallback
function is similar to C.SomeDLLFunc
.But it references goCallbackFunction
directly without cast,since I move the code from .go to .c.C.InitCallback
. Note that if we use the C.SomeDLLFunc
solution, we must write (gocallback,dllfunc) pairs.