我有一个相对较小的项目,只有几个文件(.c 和 .h)。我一直在与多个包含错误作斗争(我认为)。因此,我创建了一个 master.h 头文件,其中包含所需的每个其他头文件。所有的头文件都有
#ifndef _MY_HEADER
#define _MY_HEADER
… Header body
#endif
保护以防止多重包含。我的每个文件都包含顶部的 master.h 文件。这就是我期望它如何工作的方式。
- 编译的第一个文件会看到 #include "master.h"
- 由于这是第一次处理此文件,__MASTER 尚未定义,因此它将处理该文件。
- 编译器将包含下一个头文件,类似地,它还没有被处理,所以编译器会处理它,然后它会被定义,并且不会再次被处理。
- 这对 master.h 中的所有头文件继续进行,直到所有文件都已被处理并定义为不再被处理。
- master.h 文件也是如此。一旦处理完成,由于有守卫,将不会再次处理。
这不应该防止多重包含吗?
所以这里是错误。
Building target: My_Project_Bootloader.axf
Invoking: GNU ARM C Linker
arm-none-eabi-gcc -g3 -gdwarf-2 -mcpu=cortex-m3 -mthumb -T "C:/Users/Greg/SimplicityStudio/v4_workspace/My_Project_Bootloader/GNU ARM v4.9.3 - Debug/My_Project_Bootloader_custom.ld" -nostdlib -L"C:\GCC_STUFF" --specs=nosys.specs -Xlinker --gc-sections -Xlinker -Map="My_Project_Bootloader.map" -lm -lgcc -lc -o My_Project_Bootloader.axf "./Source/aeabi_memset-thumb.o" "./Source/crt0.o" "./Source/em_emu.o" "./Source/functions.o" "./Source/main.o" "./Source/startup_efm32jg1b.o" "./Source/interrupts.o"
./Source/main.o:(.rodata.const_ModBusIDReg+0x0): multiple definition of `const_ModBusIDReg'
./Source/functions.o:(.rodata.const_ModBusIDReg+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [My_Project_Bootloader.axf] Error 1
我已经编辑/删除了这篇文章中的一些信息,因为事实证明它是不相关的。似乎链接器遇到的“多重定义”问题不是由于实际的“多重定义”或任何变量的包含。相反,它似乎是由于同时声明和定义变量(在本例中为闪存中的 const)所致。一旦我将声明拆分为头文件,并将实际定义或分配拆分为 .c 文件,问题就消失了。以下是解决问题“变量”之一的示例。我现在将更加关注变量的声明和定义方面。使用的工具是 GCC。感谢您的所有评论。
// boot.h
// declare const array
const unsigned char const_ModBusIDReg[7][48];
// boot.c
#include boot.h
// define const array
const unsigned char const_ModBusIDReg[7][48] =
{
"String1", // reg00
"String2", // reg01
"String3", // reg02
"String4", // reg03
"String5", // reg04
"String6", // reg05
"String7" // reg06
};