C中固定内存地址上函数指针的外部数组
我正在开发一个嵌入式应用程序,需要在固定内存地址上声明一个函数指针数组,然后在不同的.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文件中使用它,我需要在各
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代码>未定义。知道为什么吗?