| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4462 人关注过本帖
标题:如何实现函数替换呢?
只看楼主 加入收藏
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
结帖率:79.17%
收藏
已结贴  问题点数:10 回复次数:16 
如何实现函数替换呢?
在单元测试中,需要实现打桩函数,我现在一直没有想通怎么定义一个函数
void Add_STUB( void *func, void* func_stub)
实现的功能要类似
#define func  func_stub 呢?
搜索更多相关主题的帖子: 函数 
2010-07-24 22:36
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
为什么一定要一个函数来做这个?靠条件预处理可不可以?

类似下面这样的:
#ifdef DEBUG
#define func func_stub
#endif

然后在定义 func_stub 地方也可以用类似的条件处理包起来。
这样编译之前指定一下 DEBUG 这个宏,所有调用的地方就会变过去。
通过后,再编译的时候,会一且正常。而且桩函数根本不会被编译。
2010-07-25 00:38
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 2楼 pangding
桩函数不被编译是错误的,因为可能程序里面仅仅需要对局部的代码进行打桩测试

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-07-25 01:46
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
程序代码:
/******************************************************************
* Copyright (c) 2010, XX Technologies Co., Ltd.
* All rights reserved.
*

* 文件名称:testStub.cpp
* 摘    要: 函数打桩测试代码
*
* 取代版本:1.0

* 原作者  :zhong yunde
* 完成日期:2010年07月24日
*******************************************************************/
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "stub.h"

#define  UNICODE
#define  _UNICODE

// 定义MessageBoxA函数原型
typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);
int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType);

unsigned * addr = (unsigned *)MessageBoxA;        // 保存函数的入口地址
unsigned * myaddr = (unsigned *)MessageBoxProxy;


int main(void)
{
    //OutputDebugString(_T("start !"));
    MessageBoxA(NULL, " 原函数", "09HookDemo", 0);
  


    AddStub(addr, myaddr); // 对 addr指向的函数进行打桩
    //用于测试的API函数
    MessageBoxA(NULL, "原函数", "09HookDemo", 0);

    //ClearStub(myaddr, addr);
    ClearStub(addr);       // 进行清桩处理

    MessageBoxA(NULL, "原函数", "09HookDemo", 0);
  


    return 0;
}

int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)
{
    return ((PFNMESSAGEBOX)addr) (NULL, "stub", "Stub", 0); // 用地址调用一个API函数
}
目前实现了需要的代码,但对于清桩处理的函数ClearStub定义使用
ClearStub(myaddr, addr); 优点:能同时对多个函数进行打桩处理,  缺点:多用了一个参数
ClearStub(addr);         缺点:只能一次对一个函数进行打桩处理,优点:参数比较少而简洁
以上两种对ClearStub定义的定义,那种比较合适呢 ?我因该怎么考虑


~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-07-25 01:51
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:10 
我说的不编译是指发布的时候。
显然测试完成之后,可能不会希望那些桩函数数还留在代码里。用条件编译可以使不指定 DEBUG 宏时编译能跳过桩函数,而且不用修改源代码。

我没干过类似的事,虽然学过软件工程,也没什么实践经验。从你举的例子里,看不出多不多个参数有什么太大差别。感觉如果能对多个桩进行处理是不是还是灵活一点好呢?

等等论坛里的其他人,看看有没什么好的建议。
2010-07-26 00:26
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
我说的大概是这意思:
程序代码:
#include <stdio.h>

void f()
{
    printf("f\n");
}

#ifdef DB
void _f()
{
    printf("_f\n");
}
#endif

#ifdef DB
#define f() _f()
#endif

int main(int argc, char *argv[])
{
    f();

    return 0;
}


不知道这样能不能满足需求。
2010-07-26 00:33
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 6楼 pangding
程序代码:
#include <stdio.h>

 #define  DB  // 设置编译开关
void f()
{
    printf("f\n");
}

void _f()
{
    printf("_f\n");
}

#ifdef DB
#define f() _f()
#endif

int main(int argc, char *argv[])
{
    f();

    return 0;
}
您上述的方法在程序中不能同时使用 f(); 和 _f();,每次只能根据编译开关DB决定是否进行整体转换

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-07-31 01:32
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
哦,桩函数不是要整个换掉的哈~ 我不是很清楚。
 
我当时学软件工程的时候以为做单元测试,是为了不把本来函数的错误引进来,或者本来函数的输出不好控制才引入桩函数的呢。这样这个模块的测试就可以和别的模块划开了。原来还是得一块用。
反正测试,调试什么的都是专门的技术。这个帖子搁置了这么久,也没其他人回,看来不太受欢迎。你要不去别的论坛问问?到时把答案带回来,也好结帖。我顺便也能学学相关的知识~~
2010-07-31 02:23
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 8楼 pangding
您能推荐哪个论坛对专门讨论测试方面的知识吗?我也刚开始用测试,以前上学时从来不测试的,对这方面还很菜

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-02 00:52
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
程序代码:
以下是引用pangding在2010-7-25 00:38:22的发言:

为什么一定要一个函数来做这个?靠条件预处理可不可以?

类似下面这样的:
#ifdef DEBUG
#define func func_stub
#endif

然后在定义 func_stub 地方也可以用类似的条件处理包起来。
这样编译之前指定一下 DEBUG 这个宏,所有调用的地方就会变过去。
通过后,再编译的时候,会一且正常。而且桩函数根本不会被编译。
#include <stdio.h>

typedef struct class1_t
{
    void dump(void) { printf("class1.\n"); }
} class1_t;

typedef struct class2_t
{
    void dump(void) { printf("class2.\n"); }
} class2_t;

void test()
{
    class1_t c1;
    c1.dump();
}


int main( int ac, char **av )
{
    class1_t c1;
    class2_t c2;

    c1.dump();
#define c1 c2
    c1.dump();
    test();
#undef c1
    c1.dump();

    return 0;
}
发现使用宏定义后,对应间接调用方式无效(test();)!

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-02 23:22
快速回复:如何实现函数替换呢?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.047915 second(s), 7 queries.
Copyright©2004-2025, BCCN.NET, All Rights Reserved