go 私有结构体 私有方法 映射

  1. 通过go:linkname的方式把方法init11映射出来
  2. 通过struct的bytes转换的方式把私有的结构体转换成当前包的结构体

a.go

github.com/pubgo/gotests/testmonkey_patch/internal/a1/a.go

type hh struct {
        HH string
}

func (t hh) init1() string {
        return t.HH
}

func Newhh(s string) *hh {
        return &hh{HH: s}
}

main.go

github.com/pubgo/gotests/testmonkey_patch/main.go

import (
        "context"
        "fmt"
        "github.com/pubgo/gotests/testmonkey_patch/internal/a1"
        _ "google.golang.org/grpc"
        "net"
        "reflect"
        "unsafe"
        _ "unsafe"
)

type hh struct {
        HH string
}

//go:linkname init11 github.com/pubgo/gotests/testmonkey_patch/internal/a1.(*hh).init1
func init11(t *hh) string

func main() {
        hh := a1.Newhh("sss")
        fmt.Println(hh.HH)
        dt := MyStructToBytes(unsafe.Pointer(hh))
        fmt.Println(BytesToMyStruct(dt).HH)
        hh1 := BytesToMyStruct(dt)
        fmt.Println(init11(hh1))
}

var sizeOfMyStruct = int(unsafe.Sizeof(hh{}))

func MyStructToBytes(s unsafe.Pointer) []byte {
        var x reflect.SliceHeader
        x.Len = sizeOfMyStruct
        x.Cap = sizeOfMyStruct
        x.Data = uintptr(s)
        return *(*[]byte)(unsafe.Pointer(&x))
}

func BytesToMyStruct(b []byte) *hh {
        return (*hh)(unsafe.Pointer(
                (*reflect.SliceHeader)(unsafe.Pointer(&b)).Data,
        ))
}