Let me tell you that you are going down a very dangerous route, which involves slow-downs due to the CGO overhead, potential crashes due to missing function references, and potential memory leaks if not being very careful.
With that disclaimer, I do not think that this will work without some kind of workaround.
Running the code example you have provided, the error is the following: cannot convert myPrivCallback (variable of type func(a _Ctype_int, b _Ctype_int) _Ctype_int) to type _Ctype_callback
When you run C.test(C.callback(C.goCallback))
you refer to a C function that has been previously exported from the go world.
When you try to run C.test(C.callback(myPrivCallback))
you are referring to a go function and not to an exported C function, hence the conversion fails, because this seems to be illegal. This is why you have to type export goCallback
to make C.test(C.callback(C.goCallback))
work in the first place.
With that being said, you may workaround the issue by putting your anonymous functions in a global map and refer to them with integers. When assigning your callback you have to put that integer in the C call and you will also have to handle a unique int counter for that purpose, but that should not be too much of an issue. Just be careful to delete unnecessary anonymous functions from your map to avoid memory leaks.
Here an example:
package main
// extern int goCallback(int ci, int a, int b);
// typedef int (*callback)(int, int, int);
//
// static void test(int ci, callback cb) {
// cb(ci, 1, 2);
// }
import "C"
import "fmt"
var cbMap map[C.int]func(a, b C.int) C.int
//export goCallback
func goCallback(ci, a, b C.int) C.int {
return cbMap[ci](a, b)
}
func init() {
cbMap = make(map[C.int]func(a C.int, b C.int) C.int)
}
func main() {
cbMap[0] = func(a, b C.int) C.int {
fmt.Println("Go callback called with", a, b)
return a + b
}
defer delete(cbMap, 0)
C.test(0, C.callback(C.goCallback))
// Problem:
// How to do this
cbMap[1] = func(a, b C.int) C.int {
fmt.Println("This is a private function called with", a, b)
return a + b
}
defer delete(cbMap, 1)
C.test(1, C.callback(C.goCallback))
// can still call the first function because it is not deleted yet
C.test(0, C.callback(C.goCallback))
}
Not the ideal solution you would like to have, I know. But I still hope that this helps!