C 我可以在头文件中看到定义,那么为什么编译器会抱怨;未定义引用“;?

C 我可以在头文件中看到定义,那么为什么编译器会抱怨;未定义引用“;?,c,arm,raspberry-pi,C,Arm,Raspberry Pi,我从模拟设备公司为他们的ad7176-2模数转换IC购买了一块开发板。我下载了“通用驱动程序文件”(不是特定于操作系统的)。 我一直在Raspberry Pi上编译它们,这是一种运行Debian变体Raspian的arm设备。 我使用Code::Blocks作为IDE,并且使用了“GNU GCC”和“GNU ARM GCC”编译器 我得到错误“未定义对'AD7176_regs'的引用” 以下是AD7176#u regs.h文件中的代码,该文件包含在AD7176.h中,AD7176.h包含在AD7

我从模拟设备公司为他们的ad7176-2模数转换IC购买了一块开发板。我下载了“通用驱动程序文件”(不是特定于操作系统的)。 我一直在Raspberry Pi上编译它们,这是一种运行Debian变体Raspian的arm设备。 我使用Code::Blocks作为IDE,并且使用了“GNU GCC”和“GNU ARM GCC”编译器

我得到错误“未定义对'AD7176_regs'的引用”

以下是AD7176#u regs.h文件中的代码,该文件包含在AD7176.h中,AD7176.h包含在AD7176.c中,编译器在AD7176.c中发现错误

守则:

    /*! AD7176 register info */
typedef struct _st_reg 
{
    int32_t addr;
    int32_t value;
    int32_t size;
}st_reg;

/*! AD7176 registers list*/
enum AD7176_registers
{
    Status_Register = 0x00,
    ADC_Mode_Register,
    Interface_Mode_Register,
    Register_Check,
    Data_Register,
    IOCon_Register,
    ID_st_reg,
    CH_Map_1,
    CH_Map_2,
    CH_Map_3,
    CH_Map_4,
    Setup_Config_1,
    Setup_Config_2,
    Setup_Config_3,
    Setup_Config_4,
    Filter_Config_1,
    Filter_Config_2,
    Filter_Config_3,
    Filter_Config_4,
    Offset_1,
    Offset_2,
    Offset_3,
    Offset_4,
    Gain_1,
    Gain_2,
    Gain_3,
    Gain_4,
    Communications_Register,
    AD7176_REG_NO
};


**Defining the undefined**


#ifdef AD7176_INIT
/*! Array holding the info for the AD7176 registers - address, initial value, size */
st_reg AD7176_regs[] = 
{
    {0x00, 0x00,   1}, //Status_Register
    {0x01, 0x0000, 2}, //ADC_Mode_Register
    {0x02, 0x0100, 2}, //Interface_Mode_Register
    {0x03, 0x0000, 3}, //Register_Check
    {0x04, 0x0000, 3}, //Data_Register
    {0x06, 0x0000, 2}, //IOCon_Register
    {0x07, 0x0000, 2}, //ID_st_reg
    {0x10, 0x8002, 2}, //CH_Map_1
    {0x11, 0x0000, 2}, //CH_Map_2
    {0x12, 0x0000, 2}, //CH_Map_3
    {0x13, 0x0000, 2}, //CH_Map_4
    {0x20, 0x0000, 2}, //Setup_Config_1
    {0x21, 0x0000, 2}, //Setup_Config_2
    {0x22, 0x0000, 2}, //Setup_Config_3
    {0x23, 0x0000, 2}, //Setup_Config_4
    {0x28, 0x020A, 2}, //Filter_Config_1
    {0x29, 0x0200, 2}, //Filter_Config_2
    {0x2a, 0x0200, 2}, //Filter_Config_3
    {0x2b, 0x0200, 2}, //Filter_Config_4
    {0x30, 0, 3}, //Offset_1
    {0x31, 0, 3}, //Offset_2
    {0x32, 0, 3}, //Offset_3
    {0x33, 0, 3}, //Offset_4
    {0x38, 0, 3}, //Gain_1
    {0x39, 0, 3}, //Gain_2
    {0x3a, 0, 3}, //Gain_3
    {0x3b, 0, 3}, //Gain_4
    {0xFF, 0, 1} //Communications_Register
};
#else
extern st_reg AD7176_regs[AD7176_REG_NO];
#endif
这里是一个我们想要访问寄存器值的地方,但是得到错误消息

        /***************************************************************************//**
* @brief Reads the conversion result from the device.
*
* @param pData - Pointer to store the read data.
*
* @return Returns 0 for success or negative error code.
*******************************************************************************/
int32_t AD7176_ReadData(int32_t* pData)
{
    int32_t ret;

    /* Read the value of the Status Register */
    ret = AD7176_ReadRegister(&AD7176_regs[Data_Register]);

    /* Get the read result */
    *pData = AD7176_regs[Data_Register].value;

    return ret;
}
如果我解决了这个问题,我应该在ARM上使用GCC还是只使用GCC。代码将在Raspberry Pi上运行,并控制开发板上的ADC IC


感谢Peter

显然,
AD7176_INIT
没有定义,因此您最终会:

extern st_reg AD7176_regs[AD7176_REG_NO];
它声明了AD7176_regs,但没有定义它,这就是为什么会出现链接器未定义引用错误的原因


现在,对象定义不应出现在头文件中,定义应放在
.c
文件中。

显然
AD7176_INIT
未定义,因此您将得到:

extern st_reg AD7176_regs[AD7176_REG_NO];
它声明了AD7176_regs,但没有定义它,这就是为什么会出现链接器未定义引用错误的原因


现在,对象定义不应该出现在头文件中,定义应该放在
.c
文件中。

是。我看到了“#define AD7176_INIT”“在公元7176.c的一开始,很奇怪它是这样写的。我将尝试将定义移动到.c文件。是否在包含
AD7176_regs.h
文件之前定义
define
?是。这是第一行。我保留了原来的定义,并将定义移到了include下面。这修复了该错误,这是唯一报告的错误。但现在我有11个错误!!如果我再次陷入困境,我会努力解决这些问题,并发布另一个问题。谢谢你解决了第一个问题啊。我应该将定义移到.c文件中吗?Peter@PeterStewart实际上,如果
define
在include之前,那么得到未定义的引用错误是没有意义的。在
.h
#ifdef AD7176_INIT
之后放置一个
#error
指令,以检查您的实际情况。关于
.c
文件中的定义,由于这些文件是由供应商提供的,我不会对它们进行太多修改,但您必须确保
.h
没有包含在其他地方,这会导致链接器多对象定义错误。这是有道理的。我将定义移回包含之前。我将#error指令放入,它表明没有定义AD7176_INIT。AD7176_INIT在所有文件中仅出现在三个位置。在枚举和AD7176_regs.h中的#else以及AD7176.c中的#define中。似乎它的唯一目的是检查定义器指令是否首先在AD7176.c中读取。我对编译知之甚少,但我现在要去查一下。是的。我在AD7176.c的最开始看到“#define AD7176_INIT”,奇怪的是它是这样写的。我将尝试将定义移动到.c文件。是否在包含
AD7176_regs.h
文件之前定义
define
?是。这是第一行。我保留了原来的定义,并将定义移到了include下面。这修复了该错误,这是唯一报告的错误。但现在我有11个错误!!如果我再次陷入困境,我会努力解决这些问题,并发布另一个问题。谢谢你解决了第一个问题啊。我应该将定义移到.c文件中吗?Peter@PeterStewart实际上,如果
define
在include之前,那么得到未定义的引用错误是没有意义的。在
.h
#ifdef AD7176_INIT
之后放置一个
#error
指令,以检查您的实际情况。关于
.c
文件中的定义,由于这些文件是由供应商提供的,我不会对它们进行太多修改,但您必须确保
.h
没有包含在其他地方,这会导致链接器多对象定义错误。这是有道理的。我将定义移回包含之前。我将#error指令放入,它表明没有定义AD7176_INIT。AD7176_INIT在所有文件中仅出现在三个位置。在枚举和AD7176_regs.h中的#else以及AD7176.c中的#define中。似乎它的唯一目的是检查定义器指令是否首先在AD7176.c中读取。我对编译知之甚少,但我现在要去查一下。