如何解决有关在C中向宏传递函数指针的警告?
我将宏定义为:如何解决有关在C中向宏传递函数指针的警告?,c,c-preprocessor,compiler-warnings,C,C Preprocessor,Compiler Warnings,我将宏定义为: #define _call(func_name, __func_proto, ...) { \ void *_handle; \ int result = !CERR_V_SUCCESS; \
#define _call(func_name, __func_proto, ...) { \
void *_handle; \
int result = !CERR_V_SUCCESS; \
\
_handle = dlopen(_DLL_NAME,GLOBAL); \
if (_handle) { \
__func_proto = dlsym(dll_handle, func_name); \
if (__func_proto) { \
result = (*__func_proto)(__VA_ARGS__); \
} \
(void)dlclose(_handle); \
} \
return (result); \
}
我使用不同的函数指针调用此宏,如下所示:
_call("download",_download,src,dst);
_call("upload",_upload,src,dst);
_call("test",_test,file);
函数指针定义为
int (*_download )(int *,int *);
int (*_upload)(int *,int*);
int (*_test)(int *,char*);
这将导致警告类型为“void*”的值不能分配给类型为“int(*)(int*,int*)”的实体。
如何解决此警告?您需要添加强制转换,因为
void*
不会自动转换为函数指针或从函数指针转换为函数指针。事实上,假设函数指针可以表示为void*
,这是不可移植的
当然,如果您在一个拥有dlopen()
和朋友的系统上,可以肯定地假设该平台支持这种转换
另外,每次调用跳整个dlopen()
*(void **)(&__func_proto) = dlsym(dll_handle, func_name);
链接后面描述了基本原理:
ISO C标准不要求函数指针可以来回转换为数据指针。实际上,ISO C标准并不要求void*类型的对象可以持有指向函数的指针。但是,支持XSI扩展的实现确实要求void*类型的对象可以包含指向函数的指针
请注意,如果尝试从void*指针转换为函数指针,则符合ISO C标准的编译器需要生成警告,如下所示:
fptr=(int(*)(int))dlsym(句柄,“my_函数”)
这是你的实际宏吗?是的,我定义了这个宏来加载一些dll,我没有在这里添加定义,但它也有定义。看起来cast丢失了,但是没有实际宏,很难判断。请继续阅读。是的,我想这是一个cast问题,与宏挑剔的定义无关:您显示的代码段不会强制转换为void*
。