C 如何使用标头中的预处理器宏命名数组的特定部分

C 如何使用标头中的预处理器宏命名数组的特定部分,c,gcc,C,Gcc,我有一个从外部设备读取的设置数组,我想使用define来提高可用性 代码 在settings.h中: #define LEN_SETTINGS 38 //Number of settings to read #define MY_FIRST_SETTING settings[0] #define MY_SECOND_SETTING settings[1] ... 在settings.c中: uint8_t settings[LEN_SETTINGS]; //Array with a

我有一个从外部设备读取的设置数组,我想使用define来提高可用性

代码

在settings.h中:

#define LEN_SETTINGS 38 //Number of settings to read

#define MY_FIRST_SETTING    settings[0]
#define MY_SECOND_SETTING   settings[1]
...
在settings.c中:

uint8_t settings[LEN_SETTINGS]; //Array with all settings updated by SPI
目标

我的目标是使用更新文件中的设置数组,并使用其他文件中的值,包括“settings.h”和
extern uint8\t settings[LEN\u SETTING]
。出于性能原因,我选择不将阵列拆分为尽可能多的变量(目标是低功耗MCU)

错误

“设置”未声明(首次在此函数中使用)设置。h行X“设置”未在标题中声明,因此我理解为什么它会给我一个错误,但无法找到解决方案

其他信息


我使用ISO C99,没有我知道的特定选项。

在头文件中添加以下行

extern uint8_t settings[LEN_SETTING];
或者对于某些编译器

extern uint8_t settings[];

设计程序的正确方法是放弃意大利面编程
extern
,转而采用私有封装。然后删除所有神秘的宏。相反,你可以这样做:

设置.h

typedef enum
{
  SETTING_FIRST,
  SETTING_SECOND,
  ...
  SETTINGS_N 

} setting_t;

uint8_t setting_get (setting_t setting);
设置.c

#include "settings.h"

static uint8_t settings [SETTINGS_N];

uint8_t setting_get (setting_t setting)
{
  return settings [setting];
}
来电者

#include "settings.h"

uint8_t data = setting_get(SETTING_FIRST);
这对于绝大多数嵌入式系统用例来说已经足够快了。如果您有极端的需求,您可以内联getter函数,牺牲适当的设计来获得一点点性能

但是请注意,如果这是一个直接从SPI填充的缓冲区,则上述内容(或extern spaghetti版本)都没有多大意义。在这种情况下,您必须处理重新进入和实时要求:

  • SPI接收数据时会发生什么情况,是通过轮询、中断还是DMA处理
  • 这些数据是如何在阵列中生成的
  • 当驱动程序和调用程序需要同时使用缓冲区时,如何处理重入情况
  • 哪些变量需要是易失的,因为它们与ISR共享或用作DMA缓冲区

等等。在编写更高层的应用程序逻辑之前,您需要先确定这些问题。

请尝试创建一个示例来向我们展示。如果您声明(您声称拥有的
extern
声明),那么您不应该得到这样的错误。您是否记得
#包括包含数组声明的头文件
?该错误与头文件的哪一行有关?那句话的内容是什么。您向我们显示的标题内容不会导致此类错误,因为此处未使用
设置。您是否在头文件中定义函数?
出于性能原因,我选择不将数组拆分为太多听起来很奇怪的变量。与数组相比,是否存在非数组变量“较慢”的假设?为什么?<代码>“设置”未在标题中声明
当然不是,您确实执行了
extern uint8\u t settings[LEN\u settings]
,但是存在
LEN\u settings
而不是
LEN\u settings
。我在用户代码的源文件中声明了extern,而不是在我的设置中。h因此出现了问题。与错误相关的行是“#首先定义我的__设置设置[0]”和类似声明的行。性能原因只是SPI函数读取外部设备填充了一个数组。如果我想一个接一个地读取设置,则传输速度要慢得多(因为对于+/-38字节使用DMA传输比对于一个字节使用38 DMA传输要好),行保持宏定义不会导致该错误。只有在实际使用该宏时,才可能出现该错误。