C++记录每个函数和参数值

5
我想在我的 C++ 应用程序中记录每个函数调用和参数值。以下是我想出的代码:
头文件:
#pragma once
class Deneme1
{
public:
    Deneme1(void);
    ~Deneme1(void);
    int Deneme1::foo1(double &a);
    int Deneme1::foo2(double &a);

    struct Logger
    {};

    template <typename T>
    struct LogReturner
    {
        T* ptrReturnValue;
        Logger& theLog;
        LogReturner(Logger& log, T* retVal) : theLog(log), ptrReturnValue(retVal) { }
        ~LogReturner() { /**/ }
    };

    #define EXPAND_ARGS(...) __VA_ARGS__;
    #define LOG_FUNCTION_CALL(x, logger, varName, ar) x varName; LogReturner<x> LR(logger, &varName); FuncCall(__FUNCTION__, EXPAND_ARGS ar);

    Logger globLogger;
};

Cpp文件:

#include "Deneme1.h"
#include "FuncCall.h"

Deneme1::Deneme1(void)
{
}

Deneme1::~Deneme1(void)
{
}

int Deneme1::foo1(double &a)
{
    LOG_FUNCTION_CALL(int, globLogger, returnValue,EXPAND_ARGS());
    Deneme1 c;
    double d = 5;
    c.foo2(d);
    return returnValue;
}

int Deneme1::foo2(double &a)
{
    LOG_FUNCTION_CALL(int, globLogger, returnValue);
    return returnValue;
}

“处理日志函数的.h文件:”
#pragma once

#include <stdio.h>
#include <cstdarg>
#include <iostream>

class FuncCall
{

public:

    FuncCall(const char * lpszFuncName, ...) { 

        printf(lpszFuncName);printf("\n"); 
        va_list arguments;                 
        double sum = 0;
        int num = 1;
        va_start ( arguments, num );            
        for ( int x = 0; x < num; x++ )          
            std::cout << va_arg ( arguments, double ) << std::endl;
        va_end ( arguments ); 

    }

   ~FuncCall() { printf("func return ");printf("\n"); }
};

编译器报错说在"LOG_FUNCTION_CALL"中找不到"EXPAND_ARGS"。实际上我不知道如何正确调用"LOG_FUNCTION_CALL"。
谢谢。
2个回答

4
对于免费函数来说,这可能会简单得多:
template <typename F, typename ...Args>
auto function_call_impl(F f, char const * fname, Args &&... args)
-> decltype(f(std::forward<Args>(args)...))
{
    std::cout << "Calling function '" << fname << "'\n";
    return f(std::forward<Args>(args)...);
}

#define CALL(function, ...) function_call_impl(function, #function, __VA_ARGS__)

使用方法:

int foo(double, char, bool);

int main()
{
    return CALL(foo, 0.5, 'x', false);
}

通过一些额外的工作,您也可以打印出参数。


谢谢您的回答。但是我想在每个需要记录日志的函数中调用此宏,而不必手动传递函数和参数名称。这个宏能提供这种功能吗? - uahakan
@uahakan: 你可以给一个使用示例吗? - Kerrek SB
@KerrekSB int Deneme1::foo2(double &a) { DBGPRINT(); // 在这里执行操作 return 1; }结果日志将会是:Deneme1::foo2 使用参数 "a=5" 进入... Deneme1::foo2 退出... - uahakan

0

从代码看来,似乎你必须列出第四个参数的参数。

 LOG_FUNCTION_CALL(int, globLogger, returnValue, a);

不确定为什么需要使用EXPAND_ARGS而不是直接在LOG_FUNCTION_CALL中使用...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接