我正在将一些C代码移植到TI DSP芯片环境中。我正在努力解决C编译器问题。
我有一个包含指向函数的指针的数据结构。我有一个初始化数据结构的函数。像这样:
typedef void (*PFN_FOO)(int x, int y);
struct my_struct
{
PFN_FOO pfn;
};
init_struct(struct my_struct *p, void *pfn)
{
p->pfn = (PFN_FOO)pfn;
}
在Visual Studio和GCC下,这种代码无需投诉即可编译。事实上,因为pfn
参数是类型void *
,所以我真的不需要在那里投一个演员;它会毫无怨言地暗中投射。
在用于TI DSP芯片的Code Composer Studio中,我收到“警告:无效类型转换”
我的政策是让我的代码在没有警告的情况下编译,所以我想解决这个问题。我尝试了各种各样的铸造。我发现如果我首先将void *
指针转换为int
,然后将其转换为正确的类型,编译器会非常高兴。呃,哎呀!
如果没有编译器抱怨,我怎么能做这个演员?我是否真的必须转发int
来关闭编译器?
注意:我特意不正在寻找“改变init_struct()
接受PFN_FOO
而不是void *
”效果的解决方案。这适用于这个简化的代码片段,但不适用于实际代码,它构建了可能异构的东西列表。
答案 0 :(得分:12)
标准C特别不支持指向数据对象的指针和指向函数的指针之间的转换。 GCC和Visual Studio支持此作为扩展。
如果要使函数符合标准(但仍然使用void *
参数),则可以将指针传递给函数指针。这是因为函数指针本身是普通对象,所以指向函数指针的指针可以转换为void *
和从init_struct(struct my_struct *p, void *pfn)
{
PFN_FOO *foo = pfn;
p->pfn = *foo;
}
转换得很好:
PFN_FOO
然后,调用者必须创建一个临时PFN_FOO fp = &somefunc;
/* ... */
init_struct(p, &fp);
对象,以便在发出呼叫时传递指针:
{{1}}
答案 1 :(得分:3)