======= 200分! 给一个函数名的字符串, 如何得到该函数地址?============

myb123 2002-10-10 04:47:33
我想实现类似sdk的函数FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
即给一个函数名的字符串, 如何得到该函数地址?

==============================

例:

FARPROC GetFuncAddress(LPCSTR lpFuncName)
{
// 如何编写实现代码?
}

void MyFunc()
{
printf("go to MyFunc.\n");
}

int main()
{
void (*pFn)();
pFn = GetFuncAddress("MyFunc");
}
...全文
89 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
icansaymyabc 2002-10-14
  • 打赏
  • 举报
回复
除非你的函数是动态链接或静态连接库,否则函数名称在编译的时候就被编译器丢弃,你真想找的话只能到阴曹地府去找了。
tuyang 2002-10-14
  • 打赏
  • 举报
回复
对于程序中的全局函数,由于在编译的过程中,编译器把函数名转换成了代码中的相对地址或绝对地址,函数名称在编译的时候已经被编译器丢弃了,从而,函数名称和函数地址就没有了对应关系。所以,从函数运行时的角度通过函数名来得到全局函数的函数地址是不可能的。如果设计的好的话,可以在设计阶段把各个全局函数名和地址建立一个对应关系表,这样就可以在运行时找到函数地址了。
myb123 2002-10-11
  • 打赏
  • 举报
回复
tuyang 与 psusong(我心飞扬)
谢谢您们了!
我的不是动态库的导出函数, 而是我的例子中那样的全局函数,
难道真要建立函数地址表才能解决问题吗?
myb123 2002-10-10
  • 打赏
  • 举报
回复
谢谢了!
mwc21@163.net
tuyang 2002-10-10
  • 打赏
  • 举报
回复
不用着急。
如果你使用的函数是类似于动态库的导出函数,能够用名字识别的,那么我就有办法给你解决。
microsoft的GetProcAddress我这儿有仿真的源程序,是从bo2k中得到的。

// Like GetProcAddress(), returns null if the procedure/ordinal is not there, otherwise returns function addr.
FARPROC GetDLLProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
if(hModule==NULL) return NULL;

// Get header

PIMAGE_OPTIONAL_HEADER poh;
poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (hModule);

// Get number of image directories in list

int nDirCount;
nDirCount=poh->NumberOfRvaAndSizes;
if(nDirCount<16) return FALSE;

// - Sift through export table -----------------------------------------------

if(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size==0) return NULL;

// Good, we have an export table. Lets get it.

PIMAGE_EXPORT_DIRECTORY ped;
ped=(IMAGE_EXPORT_DIRECTORY *)RVATOVA(hModule,poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

// Get ordinal of desired function

int nOrdinal;

if(HIWORD((DWORD)lpProcName)==0) {
nOrdinal=(LOWORD((DWORD)lpProcName)) - ped->Base;
} else {

// Go through name table and find appropriate ordinal

int i,count;
DWORD *pdwNamePtr;
WORD *pwOrdinalPtr;

count=ped->NumberOfNames;
pdwNamePtr=(DWORD *)RVATOVA(hModule,ped->AddressOfNames);
pwOrdinalPtr=(WORD *)RVATOVA(hModule,ped->AddressOfNameOrdinals);

for(i=0;i<count;i++) {

// XXX should be a binary search, but, again, fuck it.

char *svName;
svName=(char *)RVATOVA(hModule,*pdwNamePtr);

if(lstrcmp(svName,lpProcName)==0) {
nOrdinal=*pwOrdinalPtr;
break;
}

pdwNamePtr++;
pwOrdinalPtr++;
}
if(i==count) return NULL;
}

// Look up RVA of this ordinal
DWORD *pAddrTable;
DWORD dwRVA;
pAddrTable=(DWORD *)RVATOVA(hModule,ped->AddressOfFunctions);

dwRVA=pAddrTable[nOrdinal];


// Check if it's a forwarder, or a local addr
// XXX Should probably do this someday. Just don't define forwarders. You're
// XXX not loading kernel32.dll with this shit anyway.

DWORD dwAddr;
dwAddr=(DWORD) RVATOVA(hModule,dwRVA);

return (FARPROC) dwAddr;
}
GoogleGeek 2002-10-10
  • 打赏
  • 举报
回复
简单,先建立你的函数表,然后使用函数指针,无非是一种映射关系而已!
信箱?
myb123 2002-10-10
  • 打赏
  • 举报
回复
难道真的编不出
FARPROC GetFuncAddress(LPCSTR lpFuncName)
{
}
吗? 那microsoft的GetProcAddress是怎么样编的?
myb123 2002-10-10
  • 打赏
  • 举报
回复
首先谢谢!
其实pFn = GetFuncAddress(MyFunc)就是pFn = MyFunc , 我不能用你的方法;

我的源文件不是在同一个工程中使用的, 而且我就是要利用传参.
例如我有以下函数:
int mytest(LPTSTR lpExecuteFuncName)
{
void (*pFn)();
pFn = GetFuncAddress(lpExecuteFuncName);
(*pFn)();
}
tuyang 2002-10-10
  • 打赏
  • 举报
回复
如果源文件是在同一个工程中,即使用GetFuncAddress("MyFunc")函数,参数代表的函数MyFunc在本工程中实现,那么使用GetFuncAddress("MyFunc")就没有意义了。直接赋值就可以了。
void MyFunc()
{
printf("go to MyFunc.\n");
}

int main()
{
void (*pFn)();
pFn = MyFunc;
}

如果你确实想通过传递参数的方法得到函数地址的话,那么只能是这样了。

#define GetFuncAddress(A) A

使用时为
pFn = GetFuncAddress(MyFunc);

begar 2002-10-10
  • 打赏
  • 举报
回复
gz
计及源荷不确定性的综合能源生产单元运行调度与容量配置优化研究(Matlab代码实现)内容概要:本文围绕“计及源荷不确定性的综合能源生产单元运行调度与容量配置优化”展开研究,利用Matlab代码实现相关模型的构建与仿真。研究重点在于综合能源系统中多能耦合特性以及风、光等可再生能源出力和负荷需求的不确定性,通过鲁棒优化、场景生成(如Copula方法)、两阶段优化等手段,实现对能源生产单元的运行调度与容量配置的协同优化,旨在提高系统经济性、可靠性和可再生能源消纳能力。文中提及多种优化算法(如BFO、CPO、PSO等)在调度与预测中的应用,并强调了模型在实际能源系统规划与运行中的参考价值。; 适合人群:具备一定电力系统、能源系统或优化理论基础的研究生、科研人员及工程技术人员,熟悉Matlab编程和基本优化工具(如Yalmip)。; 使用场景及目标:①用于学习和复现综合能源系统中考虑不确定性的优化调度与容量配置方法;②为含高比例可再生能源的微电网、区域能源系统规划设计提供模型参考和技术支持;③开展学术研究,如撰写论文、课题申报时的技术方案借鉴。; 阅读建议:建议结合文中提到的Matlab代码和网盘资料,先理解基础模型(如功率平衡、设备模型),再逐步深入不确定性建模与优化求解过程,注意区鲁棒优化、随机优化与布鲁棒优化的适用场景,并尝试复现关键案例以加深理解。
内容概要:本文系统析了DesignData(设计数据)的存储结构,围绕其形态多元化、版本关联性强、读写特性差异化等核心特性,提出了灵活性、版本化、高效性、一致性和可扩展性五大设计原则。文章深入剖析了三类主流存储方案:关系型数据库适用于结构化元信息存储,具备强一致性与高效查询能力;文档型数据库适配半结构化数据,支持动态字段扩展与嵌套结构;对象存储结合元数据索引则有效应对非结构化大文件的存储需求,具备高扩展性与低成本优势。同时,文章从版本管理、性能优化和数据安全三个关键维度提出设计要点,建议采用全量与增量结合的版本策略、索引与缓存优化性能、并通过权限控制、MD5校验和备份机制保障数据安全。最后提出按数据形态层存储的核心结论,并针对不同规模团队给出实践建议。; 适合人群:从事工业设计、UI/UX设计、工程设计等领域数字化系统开发的技术人员,以及负责设计数据管理系统架构设计的中高级工程师和系统架构师。; 使用场景及目标:①为设计数据管理系统选型提供依据,合理选择或组合使用关系型数据库、文档型数据库与对象存储;②构建支持版本追溯、高性能访问、安全可控的DesignData存储体系;③解决多用户协作、大文件存储、历史版本管理等实际业务挑战。; 阅读建议:此资源以实际应用场景为导向,结合具体数据库类型和表结构设计进行讲解,建议读者结合自身业务数据特征,对比析不同存储方案的适用边界,并在系统设计中综合考虑成本、性能与可维护性之间的平衡。

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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