比方说,我们在库中有一个C函数funA,在funA内部,它将调用一些其他函数funB,funC等。 funB和funC可能会回调funA。所以问题是: 是否可以在funA内部检测到这种情况,例如:
void funA(void) {
if (...) {
// Calling back to funA
}
}
结论
答案 0 :(得分:3)
这可以通过使用静态标志来完成。
调用函数时,如果未设置标志,则将其设置并继续,否则立即返回。然后在函数末尾,清除标志,以便再次输入。
void funcA(void)
{
static int callback = 0;
if (callback) return;
callback = 1;
...
callback = 0;
}
如果这需要分别在多个线程中工作,则可以将变量声明为_Thread_local
而不是static
。
答案 1 :(得分:2)
如果仅是单个调用,则可以在调用此函数后设置全局/静态标志,并在开始时进行检查。或者,要消除成为单一调用的限制,可以在函数返回之前重置此标志。 像这样:
void funA(void) {
static bool used = false;
if (used)
{
printf("It is used!\n");
}
used = true;
// .... Do stuff here, including possible recursion
used = false;
}
注意-这不适用于多线程-此函数不可重入。
答案 2 :(得分:1)
也许是可以识别呼叫者的另一种方法:
void func_a(void *ptr);
void func_b(void);
void func_c(void);
void func_a(void *caller)
{
if(caller == func_a)
{
printf("called from func_a\n");
return;
}
if(caller == func_b)
{
printf("called from func_b\n");
return;
}
if(caller == func_c)
{
printf("called from func_c\n");
return;
}
if(caller == NULL)
{
printf("called from somewhere elese - going to call myself\n");
func_a(func_a);
}
}
void func_b()
{
func_a(func_b);
}
void func_c()
{
func_a(func_c);
}
int main()
{
func_b();
func_c();
func_a(NULL);
return 0;
}
答案 3 :(得分:0)
有了间接级别,您甚至可以计算函数被调用的次数:
void func( int count )
{
printf( "Count is %d\n", count );
if ( ... ) // no longer want to recurse...
{
return;
}
func( count + 1 );
}
// wrap the actual recursive call to hide the parameter
void funA()
{
func( 0 );
}
这样,它是完全线程安全的。如果您不希望使用包装函数或参数,则可以使用thread-specific storage。