如何在c中进行全局定义?为什么一次#pragma或包含防护不起作用?

问题描述 投票:0回答:1

我正在使用EFM32 PG12入门套件和Simple Studio开发显微镜的微控制器项目。在这个项目中,我在.h文件global_definitions.h

中做了一些全局的针脚和端口定义

这样做是因为复杂。不同文件中的许多功能可以直接通过思想计时器或通过PRS访问引脚。

这里是一些global_definitions.h:

#pragma once //not working

#define startUpMessage  "I:000:Initialization finished"

#define prsChannel 6

//pin definitions for the lasers

unsigned int laserPinNumbers[]={2,3,12,13,14,15};
unsigned int laserPorts[]={gpioPortA,gpioPortA,gpioPortD,gpioPortD,gpioPortD,gpioPortD};

unsigned int laserTimers[]={0,0,1,1,1,1};
#define timer0 WTIMER0
#define timer1 WTIMER1

依此类推...

如果我尝试编译我的项目,则会出现错误:

arm-none-eabi-gcc -g3 -gdwarf-2 -mcpu=cortex-m4 -mthumb -T "SLM_PG12_3.ld" -Xlinker --gc-sections -Xlinker -Map="SLM_PG12_3.map" -mfpu=fpv4-sp-d16 -mfloat-abi=softfp --specs=nano.specs -o SLM_PG12_3.axf "./CMSIS/EFM32PG12B/startup_efm32pg12b.o" "./CMSIS/EFM32PG12B/system_efm32pg12b.o" "./emlib/em_cmu.o" "./emlib/em_core.o" "./emlib/em_gpio.o" "./emlib/em_prs.o" "./emlib/em_rtc.o" "./emlib/em_rtcc.o" "./emlib/em_system.o" "./emlib/em_timer.o" "./emlib/em_usart.o" "./emlib/udelay.o" "./src/i2c.o" "./src/izi_usart.o" "./src/laserSequences.o" "./src/leds.o" "./src/main.o" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
./src/leds.o:/home/grafmakula/SimplicityStudio/v4_workspace/SLM_PG12_3/GNU ARM v7.2.1 - Debug/../src/global_definitions.h:12: multiple definition of `laserPinNumbers'
./src/laserSequences.o:/home/grafmakula/SimplicityStudio/v4_workspace/SLM_PG12_3/GNU ARM v7.2.1 - Debug/../src/global_definitions.h:12: first defined here
./src/leds.o:/home/grafmakula/SimplicityStudio/v4_workspace/SLM_PG12_3/GNU ARM v7.2.1 - Debug/../src/global_definitions.h:13: multiple definition of `laserPorts'
./src/laserSequences.o:/home/grafmakula/SimplicityStudio/v4_workspace/SLM_PG12_3/GNU ARM v7.2.1 - Debug/../src/global_definitions.h:13: first defined here
...
collect2: error: ld returned 1 exit status
make: *** [SLM_PG12_3.axf] Error 1

包括卫兵

#ifndef GLOBAL_DEFINITIONS
#define GLOBAL_DEFINITIONS
...
#endif

也无法正常工作。

Waht是在c中进行全局定义的正确方法吗?

谢谢。

c arm include global simplicity-studio
1个回答
0
投票

#pragma once在编译single源文件时会保护头文件免受多个包含。因此,如果您编译leds.c并尝试多次包含此文件,可能是从其他包含级别不同的包含文件中提取的,则编译指示可确保该文件在此编译期间仅被解析一次。编译laserSequences.c时也会发生同样的情况。

现在您已经以.o格式编译了至少2个源文件。每个人都包含一次头文件,每个人都从该头文件中声明全局变量。链接器抱怨是因为它不知道要使用哪个。

解决方法是从不在头文件中声明变量。您仅提供其外部链接的定义。声明必须在一个且仅一个源文件中进行,例如:

global_definitions.h:

#pragma once 

#define startUpMessage  "I:000:Initialization finished"
#define prsChannel 6

extern unsigned int laserPinNumbers[];
extern unsigned int laserPorts[];
extern unsigned int laserTimers[];
...

现在在.c文件的one中,可以是一个文件,也可以是其他一些文件,例如global_definitions.c,您可以声明vars:

unsigned int laserPinNumbers[]={2,3,12,13,14,15};
unsigned int laserPorts[]={gpioPortA,gpioPortA,gpioPortD,gpioPortD,gpioPortD,gpioPortD};

unsigned int laserTimers[]={0,0,1,1,1,1};

此外,#pragma once是对替换保护宏的标准的最新添加(在编译器的较早版本中可能不起作用)。它们以相同的方式工作。

© www.soinside.com 2019 - 2024. All rights reserved.