Go | 跨包访问非导出符号

Apr 21, 2025

//go:linkname 是 Go 语言中的一个编译指令(compiler directive),用于在编译期间将一个符号(函数或变量)的名称重命名成另一个符号,达到在不同包之间绕过封装直接访问非导出(unexported)标识符的效果。

  • 需要导入 unsafe 包
  • 函数或变量必须声明

使用未导出函数(示例1):

package mypkg

import _ "unsafe"

//go:linkname privateFunc runtime.internalFunc
func privateFunc()

这里 mypkg 包里的 privateFunc 会被链接为 runtime 包中的非导出函数 internalFunc,调用privateFunc() 就是调用的 runtime.internalFunc()

使用未导出函数(示例2):

package main

import (
    _ "unsafe"
    _ "github.com/xxx/yyy/zzz"  // 确保包被导入
)

//go:linkname newUUID github.com/xxx/yyy/zzz.newUUID
func newUUID() string

func main() {
    s := newUUID()
    fmt.Println(s)
}

使用未导出变量:

package yourpkg

import _ "unsafe"

//go:linkname someValue github.com/xxx/yyy/zzz.someValue
var someValue int
https://inasa.dev/posts/rss.xml