我知道当 Go 程序从 C 程序(或任何其他使用标准对齐的程序)编写的二进制文件中读取解压结构时,使用
binary.Read
,我需要在某些字段之前添加一些填充以确保在所有成员对齐的情况下正确读取结构。 例如,在下面的例子中:
type Example struct {
A int32
B int32
C int32
D int64
}
我需要在
D
成员之前添加填充以确保它对齐:
type Example struct {
A int32
B int32
C int32
_ int32
D int64
}
上面的例子很简单,但有时我需要阅读更复杂的结构,有很多成员(其中一些成员可能本身就是结构)。
目前我需要自己为我的 Go 结构进行计算,以确定我应该根据对齐方式在何处添加填充,这是一个漫长而复杂的过程。
是否有一些工具可以读取我的代码并告诉我应该在哪里添加填充?或者一些 Go 库函数可以将我的结构作为参数并告诉我应该在何处添加填充以确保它正确对齐?
我尝试过 fieldalignment 和 aligncheck 等工具,但它们仅有助于结构的内存优化,而不是在不更改成员顺序的情况下填充结构。
我需要在 D 成员之前添加填充以确保它对齐:
type Example struct { A int32 B int32 C int32 _ int32 D int64 }
Go 编译器将结构字段与填充对齐。
举个例子,
package main
import (
"fmt"
"unsafe"
)
type Example struct {
A int32
B int32
C int32
D int64
}
func main() {
var x Example
fmt.Println("Example:", unsafe.Sizeof(x), unsafe.Alignof(x))
fmt.Println()
fmt.Println("A:", unsafe.Offsetof(x.A), unsafe.Alignof(x.A), &x.A)
fmt.Println("B:", unsafe.Offsetof(x.B), unsafe.Alignof(x.B), &x.B)
fmt.Println("C:", unsafe.Offsetof(x.C), unsafe.Alignof(x.C), &x.C)
fmt.Println("D:", unsafe.Offsetof(x.D), unsafe.Alignof(x.D), &x.D)
}
https://go.dev/play/p/q0LLm_zXzZz
Example: 24 8
A: 0 4 0xc0000b8000
B: 4 4 0xc0000b8004
C: 8 4 0xc0000b8008
D: 16 8 0xc0000b8010