Go:填充结构成员以从二进制文件中读取对齐的结构

问题描述 投票:0回答:1

我知道当 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 库函数可以将我的结构作为参数并告诉我应该在何处添加填充以确保它正确对齐?

我尝试过 fieldalignmentaligncheck 等工具,但它们仅有助于结构的内存优化,而不是在不更改成员顺序的情况下填充结构。

go struct padding memory-alignment
1个回答
0
投票

我需要在 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
© www.soinside.com 2019 - 2024. All rights reserved.