获取在C/C++中调用的最后一个函数

1''*_*1'' 9 c c++ api function

我正在使用API​​,我发现自己编写了许多一般形式的错误处理代码:

if (errorCode = functionName(params)) 
    printError(errorCode, "functionName", __LINE__, __FILE__);
Run Code Online (Sandbox Code Playgroud)

身体printError可能看起来像:

fprintf(stderr, "Error in function %s on line %d of file %s", 
    functionName, lineNumber, fileNumber);
Run Code Online (Sandbox Code Playgroud)

但是,每次硬编码函数名称都是一件痛苦的事.有没有办法得到导致错误的函数的名称,即在运行时或通过宏调用的最后一个函数?当然,我无法以任何方式修改API函数.有一些方法可以获得当前函数以及调用函数,但这些函数都不能从函数外部工作.

Bry*_*hen 9

你可以拥有这个

#define SAFE_CALL(func) \
do {\
    if (errorCode = (func)) \
        printError(errorCode, #func, __LINE__, __FILE__);\
} while(0)

SAFE_CALL(functionName(params));
Run Code Online (Sandbox Code Playgroud)

  • 这不会"返回"任何东西,它不应该编译,无论你如何使用它[虽然我以前感到惊讶:). (2认同)

Ric*_*III 5

这里的解决方案是创建一个调用函数的宏,如果失败,则使用您的特殊参数调用print函数.如果您正在使用C99,那么您可以(ab)使用可变参数宏,如下所示:

void printError(const char *fmt, const char *func, const int line, const char *file, ...) {
    // the first three arguments are our function, line and file, so first, print out that first
    va_list list;
    va_start(list, file);

    // only print until the first '('
    int nchars = (int) (strchr(func, '(') - func);

    fprintf(stderr, "Error in function %.*s on line %d of file %s: ", nchars, func, line, file);
    vfprintf(stderr, fmt, list);

    va_end(list);
}

#define checkError(invoke, fmt, ...)\
do {\
    int err;\
    if ((err = (invoke))) {\
        printError(fmt, #invoke, __LINE__, __FILE__, ## __VA_ARGS__);\
    }\
} while(0)
Run Code Online (Sandbox Code Playgroud)

请注意,上面使用了GCC扩展(在clang中也支持),如果没有提供,则允许可变参数正确传递.

然后可以这样使用:

checkError(fail(), "Couldn't validate results: %s", "Context-Sensitive Debug Info");
Run Code Online (Sandbox Code Playgroud)

为您的调试乐趣输出这个可爱的文字:

Error in function fail on line 703 of file /Users/rross/Documents/TestProj/TestProj/main.mm: Couldn't validate results: Context-Sensitive Debug Info

您可能想要使用其他宏,例如GCC/Clang __PRETTY_FUNCTION__,但这应该可以帮助您入门!