阅读sync包的代码时,发现有这种调用方式:pid := runtime_procPin(),但在sync包下找不到这个方法的实现
所以查看了下runtime的代码,发现以下方法:
//go:linkname sync_runtime_procPin sync.runtime_procPin
//go:nosplit
func sync_runtime_procPin() int {
return procPin()
}
即sync包里进行函数的声明,具体实现是在runtime包
要使用这种调用方式,需要有以下几个条件:
1.添加go编译器指令 go:linkname localname [importpath.name]
2.函数声明 eg: func Hello()
3.提供.s文件,以便编译器绕过 -complete 的检查,允许不完整的函数定义
4.引入unsafe包
实践一下:
创建目录和文件
mkdir demo
cd demo
mkdir runtime
mkdir hello
touch runtime/runtime.go
touch hello/hello.go
touch hello/aa.s
touch main.go
runtime.go
package runtime
import (
"fmt"
_ "unsafe" // for go:linkname
)
//go:linkname hello_print demo/hello.Hello
func hello_print() {
fmt.Println("hello world...")
}
hello.go
package hello
import (
_ "demo/runtime"
)
func Hello()
main.go
package main
import (
"demo/hello"
)
func main() {
hello.Hello()
}
打印出:hello world...