关于arm裸机调试一个头文件的问题

2025-04-12 02:52:47
推荐回答(2个)
回答1:

1) 因为C标准和C++标准的区别,例如如下函数:
void fun(int x, int y);
c编译器编译后这个函数的名称是 __fun,而c++编译器是 __fun_int_int;(备注:_stdcall, _cdecl和_fastcall的命名方式都不相同,以上只是示例。)
这样的话如果C++编译的代码调用C编译器编译得到的库的时候,会找不到fun这个函数,导致link失败;反过来亦然。
为此C++定义了 extern "C"的标识,这个标识一方面告诉编译器,看到extern "C"定义的函数,就是用C语言的命名规范去命名,另一方面告诉link,看到这个定义,就用c语言的标准去寻找函数。

2)由于C语言不支持 extern "C" 这个标记,如果C编译时发现这个标记是会报错的。所以C++在编译C可用的库的时候,在头文件中,给函数前面加上了extern "C";但给C时,却要在头文件中把这个前缀去掉,这比较麻烦。
为此C++又定义了一个默认宏 __cplusplus。如果使用C++编译器,这个宏是默认定义了的,使用C编译器,这个宏不存在。这样:
#ifdef __cplusplus
extern "C" {
#endif
void fun(int, int);
#ifdef __cplusplus
}
#endif
就可以同时在C和C++下使用了。

3) ARM下,每个模块,例如GPIO模块,其寄存器都会在AHB BUS总线下对应一个物理地址;这个物理地址可以经过MMU又分别映射为一个虚拟的uncache和cache内存地址。
访问这个地址实际上就是访问了寄存器。
为什么结构体当中的 rGPIOACON就会控制GPIO A的GPACON寄存器呢?我想是因为结构体变量的指针被直接赋值为这个地址了。

回答2:

这个库是c写的,为了能在c++里正常引用所以加了
#ifdef __cplusplus
extern "C" {
}
#endif