大家好, C文件里定义了一个 typedef void (*start_fn_t)(const sysparam_t *param); 另外,结构体的定义: typedef struct { const char * bootver; uint32_t master_addr; uint32_t config_addr; const rsa_pub_key_t * key; }sysparam_t; extern const sysparam_t * sysparam; 最后,在一个函数里这样调用了一下 ((start_fn_t)(*(uint32_t *) (sysparam->master_addr + 4)))(sysparam); 这句话是函数的最后一句话,这句话看不懂啊。。貌似就是把一个地址强转成一个函数,然后带了个自己的参数,可是没有函数体啊。。函数使用typedef来定义的 |
2
(uint32_t *) (sysparam->master_addr + 4)
取常量指针sysparam指向内容的数据成员master_addr再偏移4,master_addr的定义是uint32_t类型的整数,但是,很显然,sysparam->master_addr成员内存放的数据是个地址值,或者为一个指针值。因此将其强制转化为(uint32_t *)
3 接下来取出这个指针指向的数据内容。
*(uint32_t *) (sysparam->master_addr + 4)
也就是说,sysparam的成员master_addr保存的数据是另一片内存的起始地址(这里暂时叫内存B)。这里只是取出这个另一片内存起始地址偏移4个字节的内容。
4 内存B中保存的是函数指针,类型为start_fn_t
因此,再次需要将内存B中的数据强制转化为start_fn_t类型才可以当做函数体来用
这个 ((start_fn_t)(*(uint32_t *) (sysparam->master_addr + 4)))()就是强制转化为start_fn_t类型的函数体。
而 ((start_fn_t)(*(uint32_t *) (sysparam->master_addr + 4)))(sysparam); 就相当于Fn(x);这样的函数调用了。
你滴,明白聊?
评分
查看全部评分
我补充一下:
1.对于
((start_fn_t)(*(uint32_t *) (sysparam->master_addr + 4)))(sysparam);
理解起来从内到外,但上面的定义略显臃肿,建议这么使用:
(*(start_fn_t*)(sysparam->master_addr+4))(sysparam);
就直接执行函数了。
2.函数到底在哪?
函数在(sysparam->master_addr+4),其实sysparam->master_addr本身就是一个函数的地址(或者不是?!)那为什么还要再加4呢?
2.1.对于sysparam->master_addr如果不是函数地址,那他在一个函数地址的前面4字节处,这种情况下,sysparam->master_addr是一个结构体成员,这个成员下一个就是函数指针了。
2.2.对于sysparam->master_addr是函数地址,再加4就到函数体里面了,当然就执行不了函数。此时只有Cortex-M中的异常向量具有这个潜质,就是跳到下一个异常函数。
2.3.楼主是不是笔误?对于(sysparam->master_addr+4)其实应该是((int)(&sysparam->master_addr)+4),这样就是在调用sysparam的config_addr成员,显然config_addr也是个函数指针。建议楼主检查下程序,是否应该如此?!
对于((int)(&sysparam->master_addr)+4),显示转换为int是必要的。否则,对于(&sysparam->master_addr)这是个int型指针,对int型指针加4相当于加了4*sizeof(int*),也就是加了0x10,显然加0x10不是我们要的。所以先把(&sysparam->master_addr)转换为int型数,再对这个数加4,此时就是sysparam_t中的config_addr成员了。
综合看这个问题,楼主除了要看明白语句的意思,还要明白程序到底要干什么,我估计程序是要对config_addr成员进行调用,但是没写对,正确的如下:
(*(start_fn_t*)((int)(&sysparam->master_addr)+4))(sysparam);