======= 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");
}
...全文
76 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

16,472

社区成员

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

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

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