C中固定内存地址上函数指针的外部数组

C中固定内存地址上函数指针的外部数组,c,C,我正在开发一个嵌入式应用程序,需要在固定内存地址上声明一个函数指针数组,然后在不同的.c文件中使用它。我想到的是: typedef void(__irq __arm * p_intr_handler_t)(void); p_intr_handler_t * IntTable = (p_intr_handler_t *)&VIM_RAM_BASE; p_intr_handler_t IntTable[95]; VIM_RAM_BASE是地址。我在main.f文件中使用它,我需要在各

我正在开发一个嵌入式应用程序,需要在固定内存地址上声明一个函数指针数组,然后在不同的.c文件中使用它。我想到的是:

typedef void(__irq __arm  * p_intr_handler_t)(void);

p_intr_handler_t * IntTable =  (p_intr_handler_t *)&VIM_RAM_BASE;
p_intr_handler_t IntTable[95];
VIM_RAM_BASE是地址。我在main.f文件中使用它,我需要在各种.c文件中使用它,所以我声明如下:

extern p_intr_handler_t IntTable[95];
extern p_intr_handler_t * IntTable;
但在尝试编译时,我收到一条错误消息: 声明与“p_intr_handler_t*IntTable”不兼容(在第3行声明) 该消息适用于普通声明和外部声明

你知道怎么了吗


谢谢

为什么要用不同的类型重新说明
IntTable

只需在单个
.c
中截取第一个定义,并在
.h
中为其创建一个
外部
以包含在另一个
.c
中,如下所示:

extern p_intr_handler_t IntTable[95];
extern p_intr_handler_t * IntTable;

显然,只有当
VIM_RAM_BASE
已经为您的数据保留了一定的空间(即编译器不会尝试将其他数据放在那里),否则您应该查看编译器的文档,看看是否有办法告诉它将变量放在内存中的特定位置。

您已经定义了两次IntTable,您不应该将其重命名为其他名称吗?

根据您尝试执行的操作,使用链接器而不是编译器执行此操作可能更有意义。在这种情况下,只需在C文件中将符号声明为
extern
(完全没有定义),并告诉链接器它在哪里。因此,您的标题将包含:

extern p_intr_handler_t IntTable[95];
然后添加一个链接时间选项(这里是GNU gcc/ld语法——其他链接器是不同的)


你可以把地址设置成你喜欢的任何地址。查看链接器的文档,看看等效选项是什么。

你说得对,我实际上声明了两次。不知怎的,我觉得我需要暗示它的大小是96…不管怎样,我照你说的做了,现在我得到了这个信息:
p_intr_hadler_t*IntTable=(p_intr_hadler_t*)&VIM_RAM_BASE
此表达式必须具有常量值和
外部p_intr_hadler_t*int表未定义…即使我将.h链接到了右侧。
VIM\u RAM\u BASE
是如何定义的?可能您不需要这个
&
。此外,您不能“链接”
.h
,而是将其包含在相关的
.c
中。它的定义如下:
\uuuuuuIO\uREG32(VIM\uRAM\uBase,0xFFF82000,\uuuuuuu READ\uwrite)
和这样的IO_REG32
#define _IO_REG32(名称、地址、属性)\volatile _no_init属性unsigned long NAME@ADDRESS
。我所说的链接是指包括。extern表达式位于一个.h文件中,该文件包含在相关的.c文件中,但错误已经出现在.h文件中,extern所在的位置。“name@address”语法是一个非标准(但有些常见)技巧,在编译器中,@Chris Dodd建议在链接器中执行。链接器方法当然也不在C标准中,但至少让您的C代码看起来很漂亮。:-)因为我无法在我的链接器(XLINK)文档中找到@Chris Dodd的建议。我想坚持我的方式,但我仍然会遇到
p\u intr\u hadler\u t*IntTable=(p\u intr\u hadler\u t*)和VIM\u RAM\u BASE必须具有常量值和
外部p\u intr\u hadler\u t*IntTable未定义。知道为什么吗?