In C you can put function pointers into an array of void pointers and convert them back to function pointers of any type:
extern int (*fn1)(void);
extern void (*fn2)(int);
void foo(void)
{
void *array[2];
int i;
/* implicit cast from function pointer to void pointer */
array[0] = fn1;
array[1] = fn2;
for (i = 0; i < 2; i++)
{
int (*fp)(int, int, int);
/* implicit cast from void pointer to function pointer */
fp = array[i];
/* call function with a different signature */
fp(1, 2, 3);
}
}
I need to do the same in Go, using unsafe.Pointers. The questions are:
- Can a Go function pointer be converted to an unsafe.Pointer?
- Can an unsafe.Pointer be converted to a Go function pointer of a different (or the same) type as the original function pointer?
(The question is not why or whether I need to do that; in the given situation it is okay to call a function with the wrong set of parameters and to misinterpret the return value because the caller and the callees are able to deal with that.)
As Jsor's answer shows, you can do this. Beware that you can do bad things:
package main
import (
"fmt"
"unsafe"
)
func main() {
f1 := func(s string) {}
f2 := func(i int) int { return i + 1 }
pointers := []unsafe.Pointer{
unsafe.Pointer(&f1),
unsafe.Pointer(&f2),
}
f3 := (*func(int) bool)(pointers[1]) // note, not int
fmt.Println((*f3)(1))
}
It appears to work:
package main
import (
"fmt"
"unsafe"
"math"
)
func main() {
fn := print
faked := *(*func(float64))(unsafe.Pointer(&fn))
faked(1.0)
// For comparison
num := math.Float64bits(1.0)
print(num)
}
func print(a uint64) {
fmt.Println(a)
}
Will print
4607182418800017408
4607182418800017408
Of course, you're probably well aware of the potential problems with trying this.
来源:https://stackoverflow.com/questions/22933169/go-convert-unsafe-pointer-to-function-pointer-and-vice-versa