是否可以在Go中获取函数引用的地址?
像
这样的东西func myFunction() {
}
// ...
unsafe.Pointer(&myFunction)
就是这样就不行了。我的猜测是不可能的,但我还没有找到任何证据。
编辑:背景
我的问题的背景来自处理CGO和C函数指针。 这有效:
/*
void go_myFunction();
typedef void (*myFunction_f)();
myFunction_f pMyFunction;
*/
import "C"
//export go_myFunction
func go_myFunction() {
// ...
}
func SetupFp() {
C.pMyFunction = (*[0]byte)(unsafe.Pointer(C.go_myFunction))
}
我也知道文档声明将指针传递给go函数不起作用。但上面的代码似乎没有那么远。我只是想知道是否可以某种方式跳过导出步骤。
答案 0 :(得分:5)
function
类型无法解决且无法比较,因为:
函数指针表示函数的代码。函数文字创建的匿名函数的代码只在内存中存储一次,无论返回匿名函数值的代码运行多少次。
如果您需要比较功能的地址,可以使用reflect.Pointer
进行比较。但是这种操作无论如何都是无意义的,因为:
如果v的类型是Func,则返回的指针是底层代码指针,但不一定足以唯一地标识单个函数。唯一的保证是当且仅当v是nil func值时结果为零。
答案 1 :(得分:2)
您可以获得这样的Go函数的地址:
package main
import (
"fmt"
"reflect"
)
func HelloWorld() {
fmt.Println("Hello, world!")
}
func main() {
var ptr uintptr = reflect.ValueOf(HelloWorld).Pointer()
fmt.Printf("0x%x", ptr)
}
答案 2 :(得分:0)
可以得到函数使用函数的地址GetFuncAddr:
package main
import (
"fmt"
"unsafe"
"reflect"
)
func HelloWorld() {
fmt.Println("Hello, world!")
}
func GetFuncAddr(i interface{}) uintptr {
type IHeader struct {
typ uintptr
word uintptr
}
return (*IHeader)(unsafe.Pointer(&i)).word
}
func main() {
tmp := HelloWorld
ptr1 := *(*uintptr)(unsafe.Pointer(&tmp)) //Way 1
ptr2 := GetFuncAddr(HelloWorld) //Way 2
fmt.Printf("0x%x = 0x%x", ptr1, ptr2)
//Thits is not are functon addrress!!!
BadPTR1 := reflect.ValueOf(HelloWorld).Pointer()
BadPTR2 := **(**uintptr)(unsafe.Pointer(&tmp)) //dereferenced pointer
fmt.Printf("\nBAD: 0x%x = 0x%x", BadPTR1 , BadPTR2 )
}