Go 和 C 中的数据结构对齐差异

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

我已经在我的 C 程序中初始化了一个结构并将其附加到共享内存。结构如下:

#define DrvMaxTag 1024
#define DrvMaxStr 128
#define StructLEN 32

typedef struct TagTypeStruct
{
    unsigned char IO;
    unsigned char Drv;
    unsigned char Class;
    unsigned char Group;
}TagTypeStruct;

typedef struct IEC_DT
{
    long int tv_Sec;
    long int tv_nSec;
}IEC_DT;

typedef struct DrvSHMTagStruct
{
    char          TagName[DrvMaxTag][DrvMaxStr];
    double        TagValue[DrvMaxTag];
    double        OldValue[DrvMaxTag];
    unsigned int  TagStatus[DrvMaxTag];
    unsigned int  OldStatus[DrvMaxTag];
    long long     TagControl[DrvMaxTag];
    IEC_DT        TagValueDT[DrvMaxTag];
    TagTypeStruct TagType[DrvMaxTag];
    int           DrvAddr[DrvMaxTag];
    unsigned char LogFlag[DrvMaxTag];
    unsigned char Freeze[DrvMaxTag];
    int           LogicState;
    char          DrvPath[DrvMaxStr];
    int           TagQuantity;
    unsigned char Instance;
}DrvSHMTagStruct;

我正在尝试从另一个用 Golang 编写的程序中读取结构。我已经计算了 C 中每个字段占用多少字节,并且在我的 Golang 结构中具有等效字段,如下所示:

const StructLEN = 32
const DrvMaxTag = 1024
const DrvMaxStr = 128

type TagTypeStruct struct {
    IO    uint8
    Drv   uint8
    Class uint8
    Group uint8
}

type IEC_DT struct {
    tv_Sec  int32
    tv_nSec int32
}

type DrvSHMTagStruct struct {
    TagName [DrvMaxTag][DrvMaxStr]byte
    TagValue   [DrvMaxTag]float64
    OldValue   [DrvMaxTag]float64
    TagStatus  [DrvMaxTag]uint32
    OldStatus  [DrvMaxTag]uint32
    TagControl [DrvMaxTag]int64
    TagValueDT [DrvMaxTag]IEC_DT
    TagType    [DrvMaxTag]TagTypeStruct
    DrvAddr    [DrvMaxTag]int32
    RetainFlag [DrvMaxTag]uint8
    Freeze     [DrvMaxTag]uint8
    LogicState int32
    DrvPath     [DrvMaxStr]uint8
    TagQuantity int32
    Instance    uint8
}

C 中结构体 (DrvSHMTagStruct) 的大小为 182416,Golang 中为 182412(我的操作系统是基于 ARM 的)。那么为什么会有这样的差异呢?它们有 4 个字节不同,有趣的是它们都工作得很好,在相同的结构上读写,没有错误。

正如我显然搜索过的那样,我了解到 C 编译器在编译过程中会进行一些“数据结构对齐”。因此,有 4 个字节的差异。但问题是,即使有 4 个字节的差异,Golang 程序如何正确地从共享内存中读取结构? 此外,当我在基于 ARM 的 Linux 上运行程序时,问题也出现了。它们在 x64 Ubuntu 上具有相同的大小。

c go data-structures shared-memory
1个回答
0
投票
Instance

。在 x86_64 版本中,它用 7 个字节填充。在 ARM 版本中,它用 3 填充。

    

© www.soinside.com 2019 - 2024. All rights reserved.