c – dladdr:指向函数的指针与指向对象的指针

希望这是一个简单的C问题(不是语言 – 律师).

如何在C中使用GNU扩展dladdr?通常会在C中写下以下内容:

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>

static void where_am_i() {}

int main()
{
  Dl_info info;
  dladdr( (void*)&where_am_i, &info );

  return 0;
}

但是使用clang可以看到演员表可能无效:

$clang --version
Debian clang version 3.6.2-3 (tags/RELEASE_362/final) (based on LLVM 3.6.2)
Target: x86_64-pc-linux-gnu
Thread model: posix
$clang -Wpedantic -o foo foo.cpp -ldl
foo.cpp:11:11: warning: cast between pointer-to-function and pointer-to-object is an extension [-Wpedantic]
  dladdr( (void*)&where_am_i, &info );
          ^~~~~~~~~~~~~~~~~~
1 warning generated.

警告对我来说似乎是合法的,那么有办法解决这个问题吗?

最佳答案
没有标准方法可以将函数指针可移植地转换为void *.因此,没有标准的方法来便携式使用dladdr.在C 11之前,这种转换是不正确的(我没有文件可用,但clang的警告暗示了它).但是,从C 11开始,有条件地支持转换:

[expr.reinterpret.cast]/8(标准草案)

Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning of such a conversion is implementation-defined, except that if an implementation supports conversions in both directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification, shall yield the original pointer value.

由于您已经依赖于提供dladdr的c库扩展,因此您可能依赖于允许您将函数指针转换为void *的语言扩展.在这种情况下,您可能希望编译器不要通过编译而不使用-Wpedantic选项来警告使用语言扩展 – 或者使用至少有条件地支持转换的标准版本.如果不支持转换,那么不是dladdr.

转载注明原文:c – dladdr:指向函数的指针与指向对象的指针 - 代码日志