在开发小型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}
答案 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 );
}