【发布时间】:2010-06-20 10:09:53
【问题描述】:
在 C++ 中,有没有办法像这样从它的指针中获取函数签名/名称?
void test(float data) {}
cout << typeid(&test).name();
我想使用这些数据进行日志记录。
【问题讨论】:
-
我们必须假设你使用的是函数指针变量,否则写成
cout << "void test(float)";?
在 C++ 中,有没有办法像这样从它的指针中获取函数签名/名称?
void test(float data) {}
cout << typeid(&test).name();
我想使用这些数据进行日志记录。
【问题讨论】:
cout << "void test(float)";?
选项 1:滚动您自己的函数名称记录器
如果您想将“指向函数的指针”解析为“函数名”,您需要创建自己的所有可用函数的查找表,然后将您的指针地址与查找表中的键进行比较,然后返回名称。
此处描述的实现:https://stackoverflow.com/a/8752173/445131
选项 2:使用__func__
GCC 提供了这个以字符串形式保存当前函数名称的神奇变量。它是 C99 标准的一部分:
#include <iostream>
using namespace std;
void foobar_function(){
cout << "the name of this function is: " << __func__ << endl;
}
int main(int argc, char** argv) {
cout << "the name of this function is: " << __func__ << endl;
foobar_function();
return 0;
}
输出:
the name of this function is: main
the name of this function is: foobar_function
注意事项:
__FUNCTION__ 是__func__ 的另一个名称。旧版本的 GCC 仅识别此名称。但是,它并不标准化。如果需要最大的可移植性,我们建议您使用__func__,但使用预处理器提供一个回退定义,如果未定义则对其进行定义:
#if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2
# define __func__ __FUNCTION__
# else
# define __func__ "<unknown>"
# endif
#endif
【讨论】:
int main (int, char**) 或类似的?)
如果你只想记录当前函数名,大多数编译器都有__FUNCTION__宏,它会在编译时给你当前函数名。
您还可以寻找堆栈遍历技术(这里是an example for Windows),它可以为您提供有关当前调用堆栈和运行时函数名称的更多信息。
【讨论】:
__func__吗? gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html 声明这在技术上不是宏。
__func__ 是标准的,它必须在那里; __FUNCTION__ 可能是一些非标准的。 __PRETTY_FUNCTION__ 也值得一提。
您无法获得函数的名称。只是因为它不驻留在可执行文件中。在您的代码编译和链接后,它会完全消失。
您可以尝试重命名您的函数/变量,并且您的可执行文件将是相同的(除了编译器可能放置的可变内容,例如构建日期/时间、调试信息 ID 等)
还可以尝试使用一些编辑器打开可执行文件并查找函数名称。你很可能找不到它。
不过,您可以添加一些程序化“装饰”,以帮助您在运行时发现您的函数名称。
【讨论】:
您无法在 C++ 中获取函数的名称,但您可以打印指针并稍后检查二进制文件(如果未剥离)以获取函数名称。签名可以完全按照您的方式打印,只是类型名称不是真正的“人类可读”。检查您的编译器文档以了解代码输出的含义。在 g++ 中,输出将是 PFvfE,我不完全理解,但它标识了一个指向函数 (F) 的指针 (F) 返回 void (v) 并采用浮点数 (f ) 作为单个参数。不要问我E是什么...
(我现在没有时间查看文档,我只是玩了一个示例程序来猜测:打印不同的函数签名)
【讨论】:
我不能 100% 确定,但这在我看来就像反射 (Java),而 C++ 不支持这样的东西。可能是我不知道,但我还没有看到 C++ 的这个。
【讨论】: