在调用函数的任何位置获取文件名和函数名

Getting file and function names wherever a function is called

本文关键字:函数 文件名 获取 任何 调用 位置      更新时间:2023-10-16

我使用宏__FILE____func__来检索文件和函数位置。我的代码结构如下。。。(注意,我使用的是游戏引擎)

测试.h

class TestClass
{
...
void Log(int status);
...
};

测试.cpp

...
void TestClass::Log(int status)
{
printf("%s %s %i",__FILE__,__func__, status);
}
...

我创建了一个类对象,并用它来记录我想要的任何东西

example.cpp

#include "Test.h"
    ...
TestClass tt;
    ...
    tt.Log((int)1);
    ...

问题是输出粘贴了Test.cpp的文件和函数名,并注意example.cpp.的文件名和函数

有没有办法解决这个问题,或者我必须一次又一次地直接使用printf语句?

感谢

您不需要在代码中的任何位置使用printf,但需要使用额外的参数__FILE____func__来调用TestClass::Log

不过,不要威胁,你可以为此创建一个宏,这样你就不必在每次调用中写下额外的参数:

#define TEST_CLASS_LOG(testClassInstance,status) 
              testClassInstance.Log((int)status, __FILE__, __func__);

而不是调用

tt.Log((int)1);

你会打电话给

TEST_CLASS_LOG(tt,1);

当然,您需要更改Log签名以考虑额外的参数:

void Log(int status, const char* fileName, const char* functionName);

此外,我看到Log没有访问任何类成员,所以你可以让它变得更容易,并使它成为static:

class TestClass
{
   static void Log(int status);
};
void TestClass::Log(int status, const char* file, const char* func)
{
   printf("%s %s %i", file, func, status);
}
#define TEST_CLASS_LOG(status) 
                  TestClass::Log((int)status, __FILE__, __func__);

所以,如果你这样做,你只需要打电话:

TEST_CLASS_LOG(1);

不幸的是,由于宏在运行时会扩展,因此在不修改代码的情况下,无法自动执行此操作。编译器现在看到的是:

void TestClass::Log(int status)
{
   printf("%s %s %i","Test.cpp","Log", status);
}

这就是为什么需要将文件名和函数名作为参数传递。

创建一个宏扩展,用额外的参数调用Log函数。像这样:

void Log(const char* filename, const char* funcname, int status)
{
  printf("%s %s %i",filename,funcname, status);
}
...
#define LOG(status) Log(__FILE__, __func__, status)
...

int foo() {
  LOG(3);
}

编辑:更详细的解释

这段代码并没有向您展示如何使用类的方法Log,它只是展示了将宏用于您想要的内容的想法。

此外,我看到的大多数日志记录实现都使用静态方法,因此不需要Logger类本身的实例。这就是为什么我没有提出一个也需要一个类成员的宏。

您可以为函数TestClass::Log()设置文件名和函数位置参数。通话内容如下:

TestClass tt;
...
tt.Log(__FILE__,__func__,(int)1);
...