C从2个函数调用中获取函数行号

时间:2015-06-19 07:23:26

标签: c gcc

在开发小型SDK的过程中,我需要创建一个"错误处理程序"。为了提高效率,我想得到函数调用的行号,我不知道它是否可以在C中使用(使用GCC进行编译)。

调用SDK函数时,如果发生错误,SDK函数本身将调用错误处理函数。

有了这个,我想知道是否有办法知道调用该函数的用户源代码中的行号。

示例:

User.c:

main{ CallSDKFunction(); }

SDK.a文件:

void CallSDKFunction( void ){ if ( ERROR ){ CallERRORHandler(); } }

... ... ...

void CallERRORHandler( void ){ // Here I want to know in which line in user.c the CallSDKFunction was called}

3 个答案:

答案 0 :(得分:1)

如果我已正确理解您的要求,您可以使用__FILE____LINE__ MACRO来获取任何指令的文件名和行号。这两个是标准的预定义MACRO。您可以查看Online GCC reference

此外,还有__func__C99)为您提供当前函数名称。

因此,您可以根据需要定义另一个函数原型(可能在debug模式下),它传递(并接受)__FILE____LINE__等额外参数,进行函数调用时__func__等。然后,您可以从被调用函数中显示调用者函数名称和行。

或者,您也可以查看backtrace()功能。但是,它是GNU扩展。

答案 1 :(得分:1)

C预处理器具有特殊标记__LINE____FILE__,它们扩展为当前行(作为整数)和当前文件(作为C字符串)。

要使其正常工作,您必须声明一个包装器宏:

void error(int line, const char *file)
{
    fprintf(stderr, "Error in %s, line %d\n", file, line);
    // handle error
}

#define ERROR() error(__LINE__, __FILE__)

这会将有关宏调用位置的信息传递给错误处理程序。

答案 2 :(得分:1)

一种方法是将__FILE____LINE__传递给SDK函数,然后让SDK函数将它们传递给错误处理函数。但是,用户不希望被打扰,因此您需要在SDK的头文件中定义一个隐藏详细信息的宏。宏看起来像这样

#define CallSDKFunction(a,b) actualSDKFunction( __FILE__, __LINE__, a, b )

用户可以使用这样的代码调用SDK。请注意,用户无需知道__FILE____LINE__正在传递给SDK功能。宏关注它。

int main( void )
{
    int a = 3;
    int b = 4;
    int result = CallSDKFunction( a, b );  
    printf( "%d\n", result );
}

SDK实现将是这样的

int actualSDKFunction( const char *fileStr, int lineNum, int a, int b )
{
    if ( a+b > 5 )
        CallERRORHandler( fileStr, lineNum );
    return( a+b );
}

void CallERRORHandler( const char *fileStr, int lineNum )
{
    printf( "Bad values in file %s at line %d\n", fileStr, lineNum );
}