如何是用函数指针实现动态调用函数?

scbb 2013-05-28 11:26:29
需求如下。

写一个共通函数,一个参数就为函数指针。
void common_func(void *func, 等)

有若干个参数个数不一样,类型也不一样的函数。
然后把函数指针传给上面的函数做调用。


//要求不能switch来判定func是什么函数。否则加一种函数就要改common_func。
//请问common_func的参数怎么定,里面怎么写?
void common_func(void *func, 等)
{
前处理

调用func所对应的函数。

后处理
}



...全文
499 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tree-New_Bee 2013-06-05
  • 打赏
  • 举报
回复
留名混脸熟。。。。
scbb 2013-06-04
  • 打赏
  • 举报
回复
引用 22 楼 adlay 的回复:
编译的时候加个 -m32 选项试试

yum install libstdc++-devel.i686
mujiok2003 2013-05-30
  • 打赏
  • 举报
回复
汇编的方案也许能工作,但是基本没有可移植性,要知道calling conventions跟编译器和CPU 架构都有关,除非你的程序没有打算做维护。
shiter 2013-05-29
  • 打赏
  • 举报
回复
厉害,强帖留名!
阿麦 2013-05-29
  • 打赏
  • 举报
回复
好象微软那么多牛人都没做到你说的这样呢。 期待你来实现。看好你哦。加油!
阿麦 2013-05-29
  • 打赏
  • 举报
回复
感觉MFC的机制对你会的帮助 afx_msg多强大
scbb 2013-05-28
  • 打赏
  • 举报
回复
引用 11 楼 adlay 的回复:
[quote=引用 9 楼 scbb 的回复:] func是一个void*, 上面的代码就不正确。
如何不正确请讲明, 我是在 VC2005 下测试过了的.[/quote] VC6报错了,从void **转换unsigned int *失败。 要改成unsigned int* argStart = (unsigned int *)&func;
www_adintr_com 2013-05-28
  • 打赏
  • 举报
回复
引用 9 楼 scbb 的回复:
func是一个void*, 上面的代码就不正确。
如何不正确请讲明, 我是在 VC2005 下测试过了的.
rocktyt 2013-05-28
  • 打赏
  • 举报
回复
引用 8 楼 anhuizhuanjiao 的回复:

#include "stdarg.h"

int  i;

void Func()
{
	i++;
}
void Func(int j)
{
	i=i+j;
}

union  Function
{
	void (*func_1)();
	void (*func_2)(int);
};

//common_func为一个可变参数函数
//第一个参数指向union,第二个参数表示Func函数的参数个数(通过它来确定调用哪一个函数)
void common_func(union Function func,int num,...)
{
	switch(num)
	{
	case 0:
		{
			func.func_1();
			break;
		}
	case 1:
		{
			va_list  ap;
			va_start(ap,num);
			func.func_2(va_arg(ap,int));
			va_end(ap);
			break;
		}
	default:
		break;
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	union Function  func;
	i=0;

	//调用无参的Func函数
	func.func_1=Func;
	common_func(func,0);

	//调用有一个参数的Func函数
	func.func_2=Func;
	common_func(func,1,3);

	return 0;
}
我只能做到这一步了,期待大神出现
lz特地说明不要用switch了
scbb 2013-05-28
  • 打赏
  • 举报
回复
引用 7 楼 adlay 的回复:
void common_func(void *func, ...) { unsigned int* argStart = &func; } [/code]
func是一个void*, 上面的代码就不正确。
转角天边 2013-05-28
  • 打赏
  • 举报
回复

#include "stdarg.h"

int  i;

void Func()
{
	i++;
}
void Func(int j)
{
	i=i+j;
}

union  Function
{
	void (*func_1)();
	void (*func_2)(int);
};

//common_func为一个可变参数函数
//第一个参数指向union,第二个参数表示Func函数的参数个数(通过它来确定调用哪一个函数)
void common_func(union Function func,int num,...)
{
	switch(num)
	{
	case 0:
		{
			func.func_1();
			break;
		}
	case 1:
		{
			va_list  ap;
			va_start(ap,num);
			func.func_2(va_arg(ap,int));
			va_end(ap);
			break;
		}
	default:
		break;
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	union Function  func;
	i=0;

	//调用无参的Func函数
	func.func_1=Func;
	common_func(func,0);

	//调用有一个参数的Func函数
	func.func_2=Func;
	common_func(func,1,3);

	return 0;
}
我只能做到这一步了,期待大神出现
www_adintr_com 2013-05-28
  • 打赏
  • 举报
回复
使用一点汇编就变得容易了, 下面是最多 20 个字节参数的版本:

#include <stdio.h>
#include <stdarg.h>

void f1(int x)
{
	printf("f1: %d\n", x);
}


void f2(int x, int y, int z)
{
	printf("f2: %d\n", x + y + z);
}

void f3(char* s)
{
	printf("f3: %s\n", s);
}


void common_func(void *func, ...) 
{
	unsigned int* argStart = &func;

	__asm {
		mov eax, argStart;
		push [eax + 0x14];
		push [eax + 0x10];
		push [eax + 0x0C];
		push [eax + 0x08];
		push [eax + 0x04];
		mov eax, func;
		call eax;
		add esp, 20;
	}
}

int main()
{
	common_func(f1, 10);
	common_func(f2, 1, 2, 3);
	common_func(f3, "Hello World!");
}
	
mujiok2003 2013-05-28
  • 打赏
  • 举报
回复
另一种方法就是模仿线程的入口函数: 把实参打包成一个结构体实例,取其地址,转换为void*,由被调用函数恢复成结构体地址.
mujiok2003 2013-05-28
  • 打赏
  • 举报
回复
使用可变参数, 这样可以不?
#include <stdio.h>      /* printf */
#include <stdarg.h>     /* va_list, va_start, va_arg, va_end */

void common(void (*pf)(va_list*), ...)
{

  va_list vl;
  va_start(vl,pf);
  pf(&vl);
  va_end(vl);
 
}

int _add(int a, int b)
{
  return a + b;
}

void add(va_list* vl)
{
   //expect two int
   int a,b;
   a = va_arg(*vl, int);
   b = va_arg(*vl, int);
   printf("%d\n", _add(a,b));
   
}

int main ()
{
  common(&add, 1, 2);
  return 0;
}
scbb 2013-05-28
  • 打赏
  • 举报
回复
引用 3 楼 starytx 的回复:
函数指针的用法应该是:比如一个函数参数为一个函数指针(返回值是bool,带两个int参数),那么定义一个这样的指针变量,这个变量可以指向任何一个返回值是bool,并且带两个int的函数
现在就是有参数不一样的多个函数想调用。 要定义多个函数指针,这个是知道的。 现在就想知道可不可以,不加type这样的变量,来区分传进来的函数是哪一种。
starytx 2013-05-28
  • 打赏
  • 举报
回复
函数指针的用法应该是:比如一个函数参数为一个函数指针(返回值是bool,带两个int参数),那么定义一个这样的指针变量,这个变量可以指向任何一个返回值是bool,并且带两个int的函数
derekrose 2013-05-28
  • 打赏
  • 举报
回复
判断不了吧。。
  • 打赏
  • 举报
回复
和变量的指针用法应该是不一样吧,如果函数返回值类型不为VOID,则调用时加一个强制转换就可以了
AnYidan 2013-05-28
  • 打赏
  • 举报
回复
有若干个参数个数不一样,类型也不一样的函数。 可否整合成一个结构体?
ayrb13 2013-05-28
  • 打赏
  • 举报
回复
用仿函数吧,还可以被编译器内联一下
加载更多回复(16)

69,371

社区成员

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

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