golang 结构体里面有指针类型的字段, 怎么计算其偏移量?

jeesk3天前0

结构体含有指针
type Stu struct {  pkg *Pkg  age int }type Pkg struct {}
pkg 字段是个私有字段, 没有办法通过 unsafe.Offsetof() 拿到,只能通过 unsafe.SizeOf() , 但是这个 pkg 字段是个指针? 这个时候要怎么计算偏移量才能获取 age 的指针, 然后拿到 age 的值?还是上面的例子,结构体里面有匿名字段
type Stu struct {  Pkg  age int }

这种情况还能通过 unsafe.SizeOf(&Pkg{}) , 这种办法能拿到 pkg 的偏移量吗?

上面两种情况要么我自己拿到的不对, 要么无处下手, 头大了。

最近被 golang 再次折磨了。

最新回复 (9)
  • ```
    package main
    import (
    "fmt"
    "unsafe"
    )
    func main() {
    stu := &Stu{
    pkg: &Pkg{},
    age: 1,
    }
    age := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(stu))+unsafe.Offsetof(stu.age)))
    fmt.Println(*age)
    }
    type Stu struct {
    pkg *Pkg
    age int
    }
    type Pkg struct {
    }
    ```
    验证可行
  • 楼主jeesk3天前
    引用3
    @chenxiankong 不我是没有办法访问到字段的,我能直接访问 stu.age ? 还用指针干毛线呀? 这里的*Pkg 的偏移量怎么算?
  • 楼主jeesk3天前
    引用4
    @chenxiankong 我是没有办法访问到字段的,我能直接访问 stu.age ? 还用指针干毛线呀? 这里的*Pkg 的偏移量怎么算?
  • @jeesk 64 位机器指针字段都是 8 字节,32 位是 4 字节,严谨一点可以通过判断机器环境 来选择取 4 还是 8
  • lujjjh3天前
    引用6
    不知道什么场景需要访问其他包结构体里的私有字段,有一种比较 tricky 的方式是直接把结构体的(部分)定义复制过来。
    比如获取 time.Time 结构体里的 ext 字段:
    https://gist.github.com/lujjjh/e92cb9904f8ec8bb42829cea0f6c2400
    当然,风险是如果以后这个结构体发生变化了,可能就没法正常运行了。
  • 0o0O0o0O0o3天前
    引用7
    如果是无源码的 hack 场景,关键词:
    data structure alignment
    memory layouts
  • 楼主jeesk3天前
    引用8
    @chenxiankong 正解 。 已经拿到了。
  • tj3u2l2天前
    引用9
    type Stu struct {
    pkg *pkg
    age int
    }
    type pkg struct {
    test string
    }
    func main() {
    s := Stu{pkg: &pkg{test: "123"}, age: 10}
    fmt.Println(unsafe.Sizeof(new(pkg)))
    fmt.Println(*(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + unsafe.Sizeof(new(pkg)))))
    }
    就 Sizeof 的参数填 pkg 的指针就好了
  • zone102天前
    引用10
    golang 有反射 reflect 这个库, 应该可以像 Python 那样根据字段名拿私有字段, 用偏移量拿说真的不是一个好习惯, 你这个例子前面只有一个字段问题还没那么大, 要是整多几个要字节对齐怎么办, 就算你全考虑到了知道怎么对齐拿到正确的字段, 这种根据编译器实现的编程方式都是坏习惯
  • 游客
    11
返回