我正在阅读code of the bitcoin trezor MCU并发现了这个:
(*(void (**)())(FLASH_APP_START + 4))();
通过分解一些东西,我试图分析这条线的含义:
( *(void (**)())(FLASH_APP_START + 4) ) ();
我可以看到这是一个没有参数的函数调用,因为最后是()
,而且函数是什么
*(void (**)())(FLASH_APP_START + 4)
指向。
我知道FLASH_APP_START + 4
会解决某些事情,所以我只需要弄清楚这是什么:
*(void (**)())
它正在解决任何void (**)()
点。但是什么是void (**)()
?它看起来像是一个函数的转换,也许。但我不确定。你能举个例子说明这个叫什么吗?你为什么需要那个?
答案 0 :(得分:2)
(void (**)())
的含义是:强制转换为指向函数返回void的指针。因此,当你取消引用它(*(void(**)())
)时,它是函数返回void的类型指针,你可以调用它。 (FLASH_APP_START+4)
是指向函数指针表的指针。如果FLASH_APP_START
的类型为char*
,则将调用列表中的第二个函数,假设32位指针。如果FLASH_APP_START
的类型为void*
,则会调用表中的第5个函数。
E.g。此代码将在具有32位指针的计算机上调用fun2
。
#include <stdio.h>
void fun1() { printf("fun1\n"); }
void fun2() { printf("fun2\n"); }
int main(void) {
static void (*table[])() = { fun1, fun2 };
int const FLASH_APP_START = (int)&table;
(*(void (**)())(FLASH_APP_START + 4))();
}
如果您需要帮助解码C类型,cdecl.org是您的朋友。
答案 1 :(得分:0)
首先,void (**)()
是指向函数指针的指针,没有参数和void返回类型。
其次,(void (**)())(FLASH_APP_START + 4)
表示在第一步中将地址值FLASH_APP_START + 4
强制转换为指针。 FLASH_APP_START
应该是固定值。它可能是NAND闪存起始地址,总是在嵌入式系统中用作向量表。
第三,*(void (**)())(FLASH_APP_START + 4)
取消引用第二步中获得的指针。我们现在有一个函数指针。
最后,(*(void (**)())(FLASH_APP_START + 4))()
调用我们在第三步中获得的函数。
摘要:地址FLASH_APP_START + 4
存储了一个函数入口地址。我们得到功能入口地址。将它转换为函数指针,然后调用它。