我已经在我的 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 上具有相同的大小。
Instance
。在 x86_64 版本中,它用 7 个字节填充。在 ARM 版本中,它用 3 填充。