在时钟生成器生成的头文件中初始化头文件中的变量是否合法?
#ifndef SI5351A_REVB_REG_CONFIG_HEADER
#define SI5351A_REVB_REG_CONFIG_HEADER
#define SI5351A_REVB_REG_CONFIG_NUM_REGS 57
typedef struct
{
unsigned int address; /* 16-bit register address */
unsigned char value; /* 8-bit register data */
} si5351a_revb_register_t;
si5351a_revb_register_t const si5351a_revb_registers[SI5351A_REVB_REG_CONFIG_NUM_REGS] =
{
{ 0x0002, 0x53 },
{ 0x0003, 0x00 },
{ 0x0007, 0x00 },
... bunch of data
};
#endif
每当我尝试使用此头文件时,都会出现错误
./si5351/Si5351A-RevB-Registers.o:(.rodata.si5351a_revb_registers+0x0): first defined here
./i2c/i2c.o:(.rodata.si5351a_revb_registers+0x0): multiple definition of `si5351a_revb_registers'
./si5351/Si5351A-RevB-Registers.o:(.rodata.si5351a_revb_registers+0x0): first defined here
collect2: error: ld returned 1 exit status
说它被多次定义。可能是因为它被我的程序中的其他文件包含在内。
但是,如果我将“typedef struct”分开放在标题中,然后放入
的大数组定义si5351a_revb_register_t const si5351a_revb_registers[SI5351A_REVB_REG_CONFIG_NUM_REGS] =
{
{ 0x0002, 0x53 },
{ 0x0003, 0x00 },
{ 0x0007, 0x00 },
... bunch of data
};
数据到自己的c文件中,#include包含它的标题。
有没有更正确的方法来使用这样的头文件?似乎应该有,如果它是生成使用的确切方式。
答案 0 :(得分:2)
您应该只声明标题中的变量,如下所示 -
extern si5351a_revb_register_t const si5351a_revb_registers[SI5351A_REVB_REG_CONFIG_NUM_REGS];
在其中一个C文件中(通常取得变量的所有权),您定义变量就像您现在所做的那样。
si5351a_revb_register_t const si5351a_revb_registers [SI5351A_REVB_REG_CONFIG_NUM_REGS] =
{
{ 0x0002, 0x53 },
{ 0x0003, 0x00 },
{ 0x0007, 0x00 },
... bunch of data
};
此文件还应包含其他位置包含的标头。
您已正确识别问题。由于标头包含在多个C文件中,因此所有文件都定义了相同的变量,并且链接器是冲突的。