在C ++中更改成员函数的地址

时间:2010-03-02 22:05:33

标签: c++ function-pointers member-function-pointers dll-injection

在C ++中,我可以通过获取成员函数的地址轻松创建函数指针。但是,是否可以更改本地功能的地址?

即。说我在同一个类中有funcA()和funcB(),定义不同。我想将funcA()的地址更改为funcB()的地址,这样在运行时调用funcA()实际上会调用funcB()。我知道这很难看,但我需要这样做,谢谢!

修改----------

我正在尝试做的背景:

我希望为现有的代码库实现单元测试,我所有模块继承的基类中的一些方法都是非虚拟的。我不允许编辑任何生产代码。我可以摆弄构建过程并在基类中替换相关的方法设置为虚拟但我认为我宁愿使用这样的黑客(我认为这是可能的)。

另外,我对技术好奇心这个话题很感兴趣,因为通过尝试解决这个问题的过程,我正在学习如何代码生成等方面。在引擎盖下的功能查找工作,我刚刚完成大学二年级的学校没有机会学习。我不确定我是否会在学校教这样的东西,因为我是在计算机工程课程而不是CS。

返回主题 方法funcA()和funcB()确实具有相同的签名,所以问题是我只能使用&获取函数的地址。运营商?我是否正确地说我不能改变函数的地址,或者在不损坏内存部分的情况下交换该地址的内容?如果将函数导出到dll,DLL注入是否适用于这种情况?

7 个答案:

答案 0 :(得分:4)

没有。函数被编译到可执行文件中,并且它们的地址在程序的整个生命周期内都是固定的。

最接近的是虚拟功能。给我们举一个你想要完成的事情的例子,我保证会有更好的方法。

答案 1 :(得分:1)

不能按照你描述的方式完成。更改静态绑定调用的目标的唯一方法是修改程序的实际可执行代码。 C ++语言没有可以实现这一目标的功能。

如果希望在运行时解析函数调用,则必须使用显式间接调用(通过函数指针调用),或使用基于运行时调用解析的语言功能(如虚函数),或者您可以使用普通分支与良好的ifswitch。在您的情况下哪个更合适取决于您的具体问题。

答案 2 :(得分:1)

从技术上讲,通过修改类型的vtable可能有可能实现虚函数,但是你肯定不能在不违反标准的情况下做到这一点(导致未定义的行为),并且需要了解特定编译器如何处理vtable。

对于其他功能,这是不可能的,因为函数的地址直接写入程序代码,程序代码通常位于只读存储区。

答案 3 :(得分:1)

你想要的是一个指向函数的指针,你可以将它指向FuncA或FuncB,假设它们具有相同的签名。

答案 4 :(得分:0)

我很确定在纯C ++中这是不可能的。 C ++不是一种动态语言。

答案 5 :(得分:0)

你无法直接做你想做的事。但是,您可以使用您已经熟悉的东西 - 函数指针,通过一些稍微不同的标准来实现类似的结果。考虑:

// This type could be whatever you need, including a member function pointer type.
typedef void (*FunctionPointer)();

struct T {
   FunctionPointer Function;
};

现在,您可以在任何给定的Function实例上设置T成员,然后调用它。这几乎是你可以合理得到的,我认为既然你已经知道了函数指针,那么你已经意识到了这个解决方案。

为什么不用您想要解决的问题的更完整描述来编辑您的问题?事实上,这听起来像是在试图做一些可怕的事情。

答案 6 :(得分:0)

简单!

有关

  

在运行时调用funcA()实际上会调用funcB()。

funcA()类似于以下内容:

int funcA( int a, int b) {
  return funcB( a, b );
}

: - )