2016-02-10 36 views
0

我读code of the bitcoin trezor MCU,发现这个:的C函数++(无效(**)())奇怪的铸造

(*(void (**)())(FLASH_APP_START + 4))(); 

通过打破一些东西,我试着来分析一下这一行的意思是:

( *(void (**)())(FLASH_APP_START + 4) )  (); 

我可以看到,这是一个没有参数的函数调用,由于()末,并且该功能是什么

*(void (**)())(FLASH_APP_START + 4) 

指向。

我知道FLASH_APP_START + 4将解决到的东西,所以我只需要弄清楚的是:

*(void (**)()) 

它解析为任何void (**)()点。但是什么是void (**)()?也许,它看起来像一个函数的转换。但我不确定。你能给我一个这个叫什么的例子吗?你为什么需要这个?

回答

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是您的朋友。

+0

返回void的函数有什么意义? – Gatonito

+0

你为什么使用typedef?它使我困惑,有没有一种方法来使用它没有typedef?你怎么能重写'空白'?是否允许? – Gatonito

+0

@Gatonito函数是一个可以用来打包代码的抽象。它不需要返回任何东西,这只是一种切断事物的方式,使人类更容易消化。具有巨大功能的代码很难理解。编译器和机器都不关心函数是否返回任何东西。 –

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。我们得到函数入口地址。将其转换为函数指针,然后调用它。

+0

参数列表'()'表示C中未指定的参数'(void)'表示没有参数。 –

+0

@ M.M好的。感谢您的评论。 – Holsety