Obtener nombres de archivos y funciones dondequiera que se llame a una función

I am using the macros __FILE__ y __func__ for retrieving the file and function location. My code is structured like this... (note i am using a game engine )

Prueba.h

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

Prueba.cpp

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

.

and i create a class object and use it to log whatever i want to.

ejemplo.cpp

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

the problem is that the output pastes the file and function name of the Test.cpp, and note the filename and function of example.cpp.

Is there a way around this or do i have to directly use the printf statement again and again?

Muchas Gracias

preguntado el 10 de marzo de 12 a las 12:03

3 Respuestas

No necesitas usar printf wherever in the code, but you will need to call TestClass::Log with extra parameters __FILE__ y __func__.

Don't threat however, you can create a macro for that so you don't have to write down the extra parameters on each call:

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

y en lugar de llamar

tt.Log((int)1);

llamarías

TEST_CLASS_LOG(tt,1);

You'd need to change the Log signature to account for the extra parameters of course:

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

Además, veo Log isn't accessing any class members, so you can make it even easier and make it 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__);

So, if you do it like this, you'd only need to call:

TEST_CLASS_LOG(1);

Unfortunately there's no way to do this automatically, without modifying your code, as macros expand at runtime. What your compiler sees now is:

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

that is why you need the file name and function name passed as parameters.

respondido 10 mar '12, 13:03

@RoverEye sure, glad to help! - Luciano Grigore

Create a macro expansion to call your Log function with extra parameters. Like this:

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);
}

EDIT: more detailed explanation

This code does not show you how to use the method Log of your class it simply showcases the idea to use macro for what you want.

Also most of the logging implementations I have seen use a static method and therefor do not require an instance of the Logger class itself. That is why I did not propose a macro that also takes a class member.

respondido 10 mar '12, 13:03

Creating a macro doesn't magically make your method a free function. It's part of a class, you can't just call it like it wasn't. - Luciano Grigore

I just gave the idea to use macro. Of course if you want to make Log a method in a class you will need to change things a bit. The log implementations I have seen usually use a static log object so actually the LOG macro does not take an additional parameter that is the object in which to log. - Ivailo Strandjev

Might want to move the comment in the answer. - Luciano Grigore

You can make file name and function location parameters to the function TestClass::Log(). The call would look similar to below:

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

respondido 10 mar '12, 13:03

Can do that, but since i am going to be using this log function many many times, it becomes a pain to use it as location parameters... - Rover Eye

@RoverEye you can define a macro so you don't have to reapeatedly use the extra parameters. - Luciano Grigore

@RoverEye: In that case, you can add a macro as Luchian's answer suggests. - Láser

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.