如何解决有关将函数指针传递给C中的宏的警告?

时间:2016-06-29 09:25:40

标签: c c-preprocessor compiler-warnings

我将宏定义为:

#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*);

这会产生警告a value of type "void *" cannot be assigned to an entity of type "int (*)(int*,int*)"

如何解决此警告?

2 个答案:

答案 0 :(得分:3)

Documentation of dlsym建议您在将其返回值指定给指针之前将函数指针强制转换为void*

*(void **)(&__func_proto) = dlsym(dll_handle, func_name);

原则在链接背后描述:

  

ISO C标准不要求指向函数的指针可以来回转换为指向数据的指针。实际上,ISO C标准不要求void *类型的对象可以保存指向函数的指针。但是,支持XSI扩展的实现确实需要void *类型的对象可以保存指向函数的指针。

     

请注意,如果尝试从void *指针到函数指针的转换,则需要符合ISO C标准的编译器生成警告:

     

fptr =(int(*)(int))dlsym(句柄," my_function");

答案 1 :(得分:1)

您需要添加强制转换,因为void *不会自动转换为/从函数指针转换。事实上,假设函数指针可以表示为void *,这是不可移植的。

当然,如果您使用的是具有dlopen()和朋友的系统,则可以肯定地假设该平台支持此转换。

另外,每次调用整个dlopen() / dlsym() / dlclose()听起来很奇怪,通常你会缓冲指针。