动态1:由函数名称调用函数

原创 2004年09月19日 00:27:00

前言:本文源于对CSDN论坛中一个问题的解答,现将其整理出来,以帮助有相同需求的朋友。

对dll进行过动态加载的朋友应该清楚GetProcAddress这个API,其作用是通过一个函数名称从dll模块中获得这个函数的地址,然后将其转换成相应的函数指针供我们调用。这便是通过函数名称来调用函数的一个典型例子。下面我们就仿真一下这个函数,主要思路就是建立一张函数映射表。

#include <iostream>
using namespace std;

// 定义函数入口结构
typedef void (*FUN_PTR)(void); 
struct fun_entry
{
    const char* fun_name; // 函数名称
    FUN_PTR fun_ptr; // 函数指针,实际上这里的数据类型也可以是整型
};

// 定义了两个原型不同的函数
void foo1() { cout << "foo1" << endl; }
int foo2(int i) { cout << "foo2:" << i << endl; return 0; }

// 定义函数映射表
fun_entry fun_entry_table[] = 
{
    {"foo1", (FUN_PTR)foo1},
    {"foo2", (FUN_PTR)foo2}
};

// 模拟GetProcAddress
FUN_PTR get_proc_address(const char* fun_name)
{
    for(int i=0; i<sizeof(fun_entry_table)/sizeof(fun_entry_table[0]); i++)
    {
        if(strcmp(fun_name, fun_entry_table[i].fun_name) == 0)
            return fun_entry_table[i].fun_ptr;
    }
    return NULL;
}

int main()
{
    typedef void (*foo1_ptr)(void);
    typedef int (*foo2_ptr)(int);
    
    foo1_ptr pfoo1 = (foo1_ptr)get_proc_address("foo1"); // 获得函数入口地址,并转换成函数指针
    if( pfoo1 ) pfoo1(); // 通过函数指针调用函数
    foo2_ptr pfoo2 = (foo2_ptr)get_proc_address("foo2");
    if( pfoo2 ) pfoo2( 100 );
    system("pause");
    return 0;
}

是不是很简单,可GetProcAddress究竟是怎么实现的呢?这个我目前还不太清楚,不过我们知道dll中有函数符号信息,可以方便的定位一个函数的入口地址。要是普通的程序的二进制代码中也有函数名称,那且不是很爽!但这样就暴露了程序的内部实现,这可大大方便了黑客,:)。

今天是9.18,勿忘国耻,振兴中华!

(freefalcon于2004.09.18)

多渠道打包之动态修改App名称,图标,applicationId,版本号,添加资源

近来公司有需求,同一套代码,要打包N套APP,而且这些APP的软件名称,软件图标,applicationId,版本号,甚至主页都不一样。之前都是单次修改,单次打包,可随着需求越来越多,需要打的包也会越...
  • abc6368765
  • abc6368765
  • 2016年10月11日 11:31
  • 6014

C++ 动态库接口制作规范

关于制作dll的一些要说要记的话。
  • CSND_Ayo
  • CSND_Ayo
  • 2016年11月28日 13:09
  • 683

【JavaScript】(4)普通函数、动态函数定义格式,调用方式,注意的详细细节

  • qq_35415600
  • qq_35415600
  • 2017年04月30日 15:01
  • 398

动态规划解决0/1背包问题

之前总结了利用穷举法,贪婪法解决0/1背包的方法,同时也通过Fibnacci介绍了动态规划,那么该如何来利用动态规划来解决0/1背包问题呢? 首先动态规划有两个条件; 如果可以把局部子问题的解结合...
  • changyuanchn
  • changyuanchn
  • 2016年05月18日 20:12
  • 2106

MyBatis,动态传入表名,字段名的解决办法

今天做项目,遇到的问题就是需求修改数据表的记录,而且字段名都不是固定的,也就是说是需要通过参数传入的, 本来这也不是什么难题,按照平常的JDBC,或者hibernate里也都好实现,可问题是现在...
  • jarniyy
  • jarniyy
  • 2016年04月16日 17:37
  • 1717

如何动态调用 C 函数

JSPatch 支持了动态调用 C 函数,无需在编译前桥接每个要调用的 C 函数,只需要在 JS 里调用前声明下这个函数,就可以直接调用: require('JPEngine').addExtens...
  • jiang314
  • jiang314
  • 2016年08月30日 18:07
  • 797

c++中静态函数与动态函数的区别

在C语言中,由于没有类
  • u013394556
  • u013394556
  • 2014年09月24日 14:01
  • 2866

AndroidStudio 动态修改版本名称

项目经理让每次打版本的时候去自动改版本名称,我一想在项目里面创建个文件不就行了,每次打包就该一下,然而被打回来了,说:“要和Svn关联起来”,万事问度娘,被我找到方法了,但是感觉写的不是很清楚,那我就...
  • u014161309
  • u014161309
  • 2016年08月01日 17:42
  • 359

【BLE】CC2541之动态更新设备名

本文以SimpleBLEPeripheral工程为例,介绍如何通过按键触发更新CC2541开发板中扫描应答的设备名...
  • feilusia
  • feilusia
  • 2016年01月14日 04:58
  • 3938

iOS关于关于动态函数的操作

前言:          Objective C的runtime技术功能非常强大,能够在运行时获取并修改类的各种信息,包括获取方法列表、属性列表、变量列表,修改方法、属性,增加方法,属性等等,本文对...
  • fanjieshao
  • fanjieshao
  • 2015年08月03日 13:46
  • 504
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:动态1:由函数名称调用函数
举报原因:
原因补充:

(最多只允许输入30个字)