type Stu struct {
pkg *Pkg
age int
}
type Pkg struct {
}
type Stu struct {
Pkg
age int
}
这种情况还能通过 unsafe.SizeOf(&Pkg{}) , 这种办法能拿到 pkg 的偏移量吗?
上面两种情况要么我自己拿到的不对, 要么无处下手, 头大了。
最近被 golang 再次折磨了。
1
chenxiankong 2022-06-23 23:10:33 +08:00
```
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 { } ``` 验证可行 |
2
jeesk OP @chenxiankong 不我是没有办法访问到字段的,我能直接访问 stu.age ? 还用指针干毛线呀? 这里的*Pkg 的偏移量怎么算?
|
3
jeesk OP @chenxiankong 我是没有办法访问到字段的,我能直接访问 stu.age ? 还用指针干毛线呀? 这里的*Pkg 的偏移量怎么算?
|
4
chenxiankong 2022-06-23 23:33:52 +08:00
@jeesk 64 位机器指针字段都是 8 字节,32 位是 4 字节,严谨一点可以通过判断机器环境 来选择取 4 还是 8
|
5
lujjjh 2022-06-24 00:17:02 +08:00 1
不知道什么场景需要访问其他包结构体里的私有字段,有一种比较 tricky 的方式是直接把结构体的(部分)定义复制过来。
比如获取 time.Time 结构体里的 ext 字段: https://gist.github.com/lujjjh/e92cb9904f8ec8bb42829cea0f6c2400 当然,风险是如果以后这个结构体发生变化了,可能就没法正常运行了。 |
6
0o0O0o0O0o 2022-06-24 00:34:56 +08:00 via iPhone
如果是无源码的 hack 场景,关键词:
data structure alignment memory layouts |
7
jeesk OP @chenxiankong 正解 。 已经拿到了。
|
8
tj3u2l 2022-06-24 02:36:38 +08:00
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 的指针就好了 |
9
zone10 2022-06-24 09:51:01 +08:00 1
golang 有反射 reflect 这个库, 应该可以像 Python 那样根据字段名拿私有字段, 用偏移量拿说真的不是一个好习惯, 你这个例子前面只有一个字段问题还没那么大, 要是整多几个要字节对齐怎么办, 就算你全考虑到了知道怎么对齐拿到正确的字段, 这种根据编译器实现的编程方式都是坏习惯
|