package a func test() { println("this is a/test()") } type A struct { Name string } func (*A) test1() { println("this is a/(*A).test1()") } func (A) test2() { println("this is a/A.test2()") } func (a *A) setName(name string) { a.Name = name } func (a *A) getName() string { return a.Name }
package b import ( "gitlab.meitu.com/mtgo/fw/fortest/a" _ "unsafe" // linkname require unsafe ) //go:linkname Test gitlab.meitu.com/mtgo/fw/fortest/a.test func Test() // 指针接收器 //go:linkname Test1 gitlab.meitu.com/mtgo/fw/fortest/a.(*A).test1 func Test1(_ *a.A) // 非指针接收器 //go:linkname Test2 gitlab.meitu.com/mtgo/fw/fortest/a.A.test2 func Test2(_ a.A) //go:linkname GetName gitlab.meitu.com/mtgo/fw/fortest/a.(*A).getName func GetName(_ *a.A) string //go:linkname SetName gitlab.meitu.com/mtgo/fw/fortest/a.(*A).setName func SetName(_ *a.A, name string)
package main import ( "fmt" "gitlab.meitu.com/mtgo/fw/fortest/a" "gitlab.meitu.com/mtgo/fw/fortest/b" ) func main() { b.Test() var v a.A b.Test1(&v) b.Test2(v) b.SetName(&v, "robin") fmt.Println(b.GetName(&v)) } /* output: this is a/test() this is a/(*A).test1() this is a/A.test2() robin */
需要注意的是,在b包的目录下需要放个.s后缀的文件,原因在于Go在编译的时候会启用-complete编译器flag,它要求所有的函数必需包含函数体。创建一个空的汇编语言文件绕过这个限制。
附:有局限的小玩意,见 https://github.com/alangpierce/go-forceexport
近期评论