不同参数,不同返回值的函数,用函数指针存储,并且动态的调用的问题

[复制链接]
查看11 | 回复5 | 2011-9-13 02:35:11 | 显示全部楼层 |阅读模式
昨天看到有人在问这个问题(170分的报酬),开始感觉把不同函数存储在一个地方很简单,用void*指针数组就可以了,后来才发现却很棘手,因为要动态调用void*指针函数,编译器必须要知道函数的具体类型.埋头搞了1个小时终于写了一个比较简单类可以解决这类问题.可是问题已经关闭了.170分泡汤了.不甘心,把这个类分享给大家吧.#includeiostream#includemap#includevectorusingnamespacestd;classFuncSet{private:mapvoid*,intm_funMap;vectorvoid*m_vecFunc;void*m_pFunc;public:voidAddFuncPtr(void*pFunc,intnumParams){m_funMap.insert(mapvoid*,int::value_type(pFunc,numParams));m_vecFunc.push_back(pFunc);}unsignedintoperator()(...){void*pFunc=m_pFunc;intnNumParams=m_funMap[pFunc];intnOffset=nNumParams*4;unsignedintnRet=0;__asm{movecx,nNumParamsmovesi,ebpaddesi,8addesi,nOffsetL1:push[esi]subesi,4loopL1callpFuncmovnRet,eaxmovecx,nNumParamsL2:popeaxloopL2}returnnRet;}FuncSetreturn*this;}FuncSet=m_vecFunc.size())throwruntime_error(\"索引越界\");m_pFunc=m_vecFunc;return*this;}};intriver(intlength,intwidth){cout\"riverlength=\"length\"\\t\"\"riverwidth=\"widthendl;return13;}char*prnt(char*pstr){coutpstrendl;return\"Thequickbrownfoxjumpsoverthelazydog\";}intintplus(inti,intj,intk){returnijk;}intmain(){FuncSetfs;void*p[]={river,prnt,intplus};void*q=p[2];fs.AddFuncPtr(river,2);//加入函数指针,指明要函数接受的参数的数量fs.AddFuncPtr(prnt,1);//通过函数名字加入fs.AddFuncPtr(q,3);//通过void*指针加入coutfs[river](20,10)endl;//通过函数名索引输出\"riverlength=20,riverwidth=10\"coutfs[q](10,20,30)endl;//通过void*指针索引输出102030=60coutfs[2](30,15,21)endl;//通过下标索引输出301521=66q=prnt;cout(char*)fs[q](\"Theromanisn\'tburntinaday\")endl;//输出\"Theromanisn\'tburntinaday\"}FuncSet可以保存一大堆不同返回类型,不同形参数目的函数,并且可以在运行的时候,动态的调用,只要提供函数名或者void*指针,或者一个索引就可调用.很灵活,但因为编译器不支持这种行为,所以也不会对其检查.可靠性只能靠写代码的人了。代码比较凌乱,用得着的朋友可以自己整理下.FuncSet类在VS2008XP测试通过.
回复

使用道具 举报

千问 | 2011-9-13 02:35:11 | 显示全部楼层
参数压栈:L1:push[esi]subesi,4loopL1函数回调,并回写返回值:callpFuncmovnRet,eax参数出栈:L2:popeaxloopL2赞个先。intnOffset=nNumParams*4;unsignedintnRet=0;将这个修改成intnOffset=nNumParams*sizeof(param_type);ret_typenRet=0;.......不是可以更通用?你很专业,函数调用的通用,必须考虑到参数压栈这个事实,在编译时期可以通过函数的类型告诉编译器,参数入栈的规范和需要入栈的大校要绕过编译时期,只能手动准备参数被动用子例程使用。对了,像这种嵌入汇编编程,参考什么书籍比较好?原来在学校的时候,简单了解过,但如何在内存中,把寄存器和当前变量的地址连接起来,我一直不是很清楚。高人,推崇几本专业点书籍吧。追问AssemblyLanguageForIntel-BasedComputers4EWindows环境下32位汇编语言程序设计(第二版)
回复

使用道具 举报

千问 | 2011-9-13 02:35:11 | 显示全部楼层
多谢!
回复

使用道具 举报

千问 | 2011-9-13 02:35:11 | 显示全部楼层
SF
回复

使用道具 举报

千问 | 2011-9-13 02:35:11 | 显示全部楼层
高手啊,汇编都用上了
回复

使用道具 举报

千问 | 2011-9-13 02:35:11 | 显示全部楼层
看得我云里雾里的,高手啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行