【问题标题】:Linker: Undefined Reference for const C structs which are located in static lib链接器:位于静态库中的 const C 结构的未定义参考
【发布时间】:2014-04-28 12:06:24
【问题描述】:

我有以下问题:

头文件“can_settings.h”:

#ifndef CAN_SETTINGS_H_
#define CAN_SETTINGS_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "can.h"

extern const CAN_InitTypeDef can_initstruct;

extern const CAN_FilterInitTypeDef can_filter_acceptall;
extern CAN_FilterInitTypeDef can_filter_1;
extern CAN_FilterInitTypeDef can_filter_2;


#ifdef __cplusplus
}
#endif

#endif

源文件“can_settings.c”:

#include "can_settings.h"

const CAN_InitTypeDef can_initstruct = {
#ifdef SYSCLK_FREQ_72MHz
    // APB1_freq = 36 MHz
    /* .CAN_Prescaler = */ 24,
    /* .CAN_Mode = */ CAN_Mode_Normal,
    /* .CAN_SJW = */ CAN_SJW_1tq,
    /* .CAN_BS1 = */ CAN_BS1_8tq,
    /* .CAN_BS2 = */ CAN_BS2_3tq,
#elif defined SYSCLK_FREQ_24MHz
    // APB1_freq = 24 MHz
    /* .CAN_Prescaler = */ 16,
    /* .CAN_Mode = */ CAN_Mode_Normal,
    /* .CAN_SJW = */ CAN_SJW_1tq,
    /* .CAN_BS1 = */ CAN_BS1_8tq,
    /* .CAN_BS2 = */ CAN_BS2_3tq,
#endif
    /* .CAN_TTCM = */ DISABLE,
    /* .CAN_ABOM = */ DISABLE,
    /* .CAN_AWUM = */ DISABLE,
    /* .CAN_NART = */ DISABLE,
    /* .CAN_RFLM = */ DISABLE,
    /* .CAN_TXFP = */ ENABLE,
};

const CAN_FilterInitTypeDef can_filter_acceptall = {
    /* .CAN_FilterIdHigh = */ 0x0000,
    /* .CAN_FilterIdLow = */ 0x0000,
    /* .CAN_FilterMaskIdHigh = */ 0x0000,
    /* .CAN_FilterMaskIdLow = */ 0x0000,
    /* .CAN_FilterFIFOAssignment = */ 0,
    /* .CAN_FilterNumber = */ 0,
    /* .CAN_FilterMode = */ CAN_FilterMode_IdMask,
    /* .CAN_FilterScale = */ CAN_FilterScale_32bit,
    /* .CAN_FilterActivation = */ ENABLE
};

const CAN_FilterInitTypeDef can_filter_1 = {
        /* .CAN_FilterIdHigh = */ 0x0000,
        /* .CAN_FilterIdLow = */ CAN_ID_EXT,
        /* .CAN_FilterMaskIdHigh = */ 0x14FC << 3,
        /* .CAN_FilterMaskIdLow = */ CAN_ID_EXT,
        /* .CAN_FilterFIFOAssignment = */ 0,
        /* .CAN_FilterNumber = */ 0,
        /* .CAN_FilterMode = */ CAN_FilterMode_IdMask,
        /* .CAN_FilterScale = */ CAN_FilterScale_32bit,
        /* .CAN_FilterActivation = */ ENABLE
};

const CAN_FilterInitTypeDef can_filter_2 = {
        /* .CAN_FilterIdHigh = */ 0x0000,
        /* .CAN_FilterIdLow = */ CAN_ID_EXT,
        /* .CAN_FilterMaskIdHigh = */ 0x1400 << 3,
        /* .CAN_FilterMaskIdLow = */ CAN_ID_EXT,
        /* .CAN_FilterFIFOAssignment = */ 0,
        /* .CAN_FilterNumber = */ 1,
        /* .CAN_FilterMode = */ CAN_FilterMode_IdMask,
        /* .CAN_FilterScale = */ CAN_FilterScale_32bit,
        /* .CAN_FilterActivation = */ ENABLE
};

链接器返回对 'can_initstruct' can_filter_acceptall' 'can_filter_1' 'can_filter_2' 的未定义引用... 文件 can_settings.{c, h} 构建为静态库,并在我的主应用程序(仅 C)和我的 CAN 低级驱动程序 (C++) 中使用。 所有静态库都是在构建我的低级驱动程序和主应用程序之前构建的。 使用 objdump,我转储了静态 CAN 设置库,并且所有上述结构都按原样列在 .rodata 部分中。 我做错了什么...?

【问题讨论】:

    标签: c


    【解决方案1】:

    如果您使用的是 GCC,请确保以正确的顺序指定库。详细说明见Why does the order in which libraries are linked sometimes cause errors in GCC?

    但是,如果您不想打扰文库序​​列,只需指定序列两次 而不是一次。应用于上述问题的公认答案,这意味着:

    gcc prog.o libA.a libB.a libA.a libB.a -o prog.x
    

    作为替代方案,使用 GCC (GCC: what are the --start-group and --end-group command line options?) 的 -Wl,--start-group ... -Wl,--end-group 标志。

    【讨论】:

      【解决方案2】:

      好的,我明白了。 指定目标文件和库的顺序在 GCC 中非常重要! 链接器搜索按照它们出现的顺序进行思考,因此如果您有一个包含对库函数的调用的源文件,您需要将它放在库之前,否则链接器将不知道它必须解析它。而且我做错了...

      感谢您的提示。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-14
        相关资源
        最近更新 更多