多个函数调用函数A,在A函数内部需要知道调用者函数的名称

straing 2015-12-03 11:15:56
题目:多个函数调用函数A,在A函数内部需要知道调用者函数的名称
限制:不能明显的在其他函数中传入函数名称作为A的参数,修改代价太大。
如:
#include "stdio.h"
#define FUNCTIONNAME __FUNCTION__
#define getfunname((a)) add_sum((a),FUNCTIONNAME)
int addsum(int a ,int b)
{
char caller[512];

snprintf(caller,512,"%s",FUNCTIONNAME);
return getfunname(a+b);
}
int addsum_b(int a,int b)
{
char caller[512];

snprintf(caller,512,"%s",FUNCTIONNAME);
return getfunname(a+b);
}
int add_sum(int sum,char name)//???这里到底该怎么解决?
{
char caller[512];
snprintf(caller,512,"%s",name);

printf("%x\n",caller);
return sum;
}

int main()
{
addsum(12,123);
addsum_b(12,123);
return 0;
}
...全文
161 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
straing 2015-12-06
  • 打赏
  • 举报
回复
这个应该是最简单的实现了,我当时没想到直接把宏作为一个字符串传入。谢谢。
引用 2 楼 chehw_1 的回复:



#include <stdio.h>

#define call(fn) call_fn(fn, __FUNCTION__)

typedef void (*FUNC_A)();


void call_fn(FUNC_A fn, const char * caller_name)
{
	printf("called from [%s]: ", caller_name);
	fn();
}

void a()
{
	printf("I'm func a.\n");
}

void b()
{
	call(a);
}

void c()
{
	call(a);
}

void d()
{
	call(a);
}

int main(int argc, char **argv)
{
	b();
	c();
	d();
	return 0;
}

均陵鼠侠 2015-12-05
  • 打赏
  • 举报
回复
2L的思路是正确的。必须按这一思路来。 如果原来的程序是这样的(fpub是公共函数,其它函数都调用fpub):
void fpub (int x, float y) {/* …… */}
void f1 (void) {fpub(1, 1.0f);}
 void f2 (void) {fpub(1, 1.0f);}
 void f3 (void) {fpub(1, 1.0f);}
 int main (void) {f1 (); f2 (); f3 (); fpub (2,2.0f); return 0;}
现在,我们希望在fpub内部获取并打印调用者的名字,则可以将fpub改为fpub_new,将原来的fpub改为宏,其它任何东西都不用变:
void fpub_new (int x, float y, const char * s) {/* …… */; __builtin_printf ("%s\n", s);}
 # define fpub(m, n) fpub_new (m, n, __func__)
 void f1 (void) {fpub (1, 1.0f);}
 void f2 (void) {fpub (1, 1.0f);}
 void f3 (void) {fpub (1, 1.0f);}
 int main (void) {f1 (); f2 (); f3 (); fpub (2,2.0f); return 0;}
均陵鼠侠 2015-12-05
  • 打赏
  • 举报
回复
2L的思路是正确的。必须按这一思路来。 如果原来的程序是这样的(fpub是公共函数,其它函数都调用fpub): void fpub (int x, float y) {/* …… */} void f1 (void) {fpub(1, 1.0f);} void f2 (void) {fpub(1, 1.0f);} void f3 (void) {fpub(1, 1.0f);} int main (void) {f1 (); f2 (); f3 (); fpub (2,2.0f); return 0;} 现在,我们希望在fpub内部获取并打印调用者的名字,则可以将fpub改为fpub_new,将原来的fpub改为宏,其它任何东西都不用变: void fpub_new (int x, float y, const char * s) {/* …… */; __builtin_printf ("%s\n", s);} # define fpub(m, n) fpub_new (m, n, __func__) void f1 (void) {fpub (1, 1.0f);} void f2 (void) {fpub (1, 1.0f);} void f3 (void) {fpub (1, 1.0f);} int main (void) {f1 (); f2 (); f3 (); fpub (2,2.0f); return 0;}
straing 2015-12-05
  • 打赏
  • 举报
回复
自己需要实现的功能,不是题目。
引用 1 楼 cyfcsd 的回复:
楼主这是一道题啊还是你自己要实现的功能啊
赵4老师 2015-12-04
  • 打赏
  • 举报
回复
#include <stdio.h>
void whocallme();
void fun1() {
    whocallme();
}
void fun2() {
    whocallme();
}
void fun3() {
    fun1();
}
void whocallme() {
    int *_esp,i;
    __asm {
        mov eax,esp
        mov _esp,eax
    }
    printf("\nfun1,fun2,fun3,_esp=%08x,%08x,%08x,%08x\n",(int)fun1,(int)fun2,(int)fun3,(int)_esp);
    for (i=0;i<100;i++) if (_esp[i]==(int)_esp) break;
    if (i<100) {
        printf("ret addr=%08x\n",_esp[i+2]);
        if ((int)fun1<=_esp[i+2] && _esp[i+2]<(int)fun2) printf("fun1 callme\n");
        if ((int)fun2<=_esp[i+2] && _esp[i+2]<(int)fun3) printf("fun2 callme\n");
    }
}
void main() {
    fun2();
    fun1();
}
//C:\tmp\tmp\Debug>tmp
//
//fun1,fun2,fun3,_esp=00401000,00401020,00401040,0012fe84
//ret addr=0040102e
//fun2 callme
//
//fun1,fun2,fun3,_esp=00401000,00401020,00401040,0012fe84
//ret addr=0040100e
//fun1 callme
//
//C:\tmp\tmp\Debug>cd ..\release
//
//C:\tmp\tmp\Release>tmp
//
//fun1,fun2,fun3,_esp=00401000,0040100a,00401014,0012ff5c
//ret addr=00401012
//fun2 callme
//
//fun1,fun2,fun3,_esp=00401000,0040100a,00401014,0012ff5c
//ret addr=00401008
//fun1 callme
//
chehw_1 2015-12-04
  • 打赏
  • 举报
回复
引用 6 楼 piplu 的回复:
... 2楼的实现原理就是在每个调用函数执行前先将自己的函数名打印出来,然后再去调用a。 楼主的意思是a需要知道是谁调用自己啊。 b(), c(), d()的做法基本就是调用A前,先打印自己,然后调用a, a仍然不知道谁调用它。
如果定义一个与a()相同的宏,使得看起来像是在a()内部实现的,不知这种方法是否适合楼主的要求:


#include <stdio.h>

#define call(fn) call_fn(fn, __FUNCTION__)

typedef void (*FUNC_A)();


void call_fn(FUNC_A fn, const char * caller_name)
{
	printf("called from [%s]: ", caller_name);
	fn();
}

void a()
{
	printf("I'm func a.\n");
}

#define a() call_fn(a, __FUNCTION__)

void b()
{
	call(a);
}

void c()
{
	a(); // 
}

void d()
{
	call(c);
}


int main(int argc, char **argv)
{
	a();
	b();
	c(); 
	d();	
	return 0;
}
输出结果: called from [main]: I'm func a. called from [b]: I'm func a. called from [c]: I'm func a. called from [d]: called from [c]: I'm func a.
piplu 2015-12-04
  • 打赏
  • 举报
回复
引用 2 楼 chehw_1 的回复:



#include <stdio.h>

#define call(fn) call_fn(fn, __FUNCTION__)

typedef void (*FUNC_A)();


void call_fn(FUNC_A fn, const char * caller_name)
{
	printf("called from [%s]: ", caller_name);
	fn();
}

void a()
{
	printf("I'm func a.\n");
}

void b()
{
	call(a);
}

void c()
{
	call(a);
}

void d()
{
	call(a);
}

int main(int argc, char **argv)
{
	b();
	c();
	d();
	return 0;
}

2楼的实现原理就是在每个调用函数执行前先将自己的函数名打印出来,然后再去调用a。 楼主的意思是a需要知道是谁调用自己啊。 b(), c(), d()的做法基本就是调用A前,先打印自己,然后调用a, a仍然不知道谁调用它。
piplu 2015-12-04
  • 打赏
  • 举报
回复
如果你只是限制了被调用的函数的参数中不能带caller的函数名,那是不是可以换一种思路,用一个全局变量来保存每次调用者的函数名称呢? 谁去调用,就把自己的函数名给到这个全局变量,被调函数被执行时去查一个这个变量就知道了? 我想的比较简单。 哈哈! 另外如果是linux平台好像有lbacktrace和backtrace_symbols这样的API可以获取函数自己的堆栈,windows就不知道了!
Saleayas 2015-12-04
  • 打赏
  • 举报
回复
很简单的。 但是必须是源码级别的。 因为编译后,名字就没有了。 使用宏来模拟。 很多调试代码都是这样的。 void a(...); void _a(function, ...) { TRACE("%s", function); a(...); } #define a(...) _a(__FUNCTION__, __VA_ARGS__)
linzertling 2015-12-04
  • 打赏
  • 举报
回复
在main函数中,调用add_sum函数时输入的参数一个是int型一个是char型,但楼主明显输入了两个int型参数,达不到所需要求
chehw_1 2015-12-04
  • 打赏
  • 举报
回复



#include <stdio.h>

#define call(fn) call_fn(fn, __FUNCTION__)

typedef void (*FUNC_A)();


void call_fn(FUNC_A fn, const char * caller_name)
{
	printf("called from [%s]: ", caller_name);
	fn();
}

void a()
{
	printf("I'm func a.\n");
}

void b()
{
	call(a);
}

void c()
{
	call(a);
}

void d()
{
	call(a);
}

int main(int argc, char **argv)
{
	b();
	c();
	d();
	return 0;
}

flying_music 2015-12-04
  • 打赏
  • 举报
回复
楼主这是一道题啊还是你自己要实现的功能啊

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧