如何将类方法的地址转换为(void *)

时间:2011-10-31 15:40:42

标签: c++ visual-c++ gcc architecture x86

class Foo{
public:
    void Bar();
}

它不必是安全的,我不关心this指针。我只需要在 x86

的内存中找到Bar函数的地址

void *address = (void *)&(Foo::Bar)不起作用。

void *address = (void *)(&Foo::Bar)不起作用。

void *address = (void *)Foo::Bar不起作用。

编辑:让我澄清一下。即使理论上将函数指针强制转换为对象也是非法的,因为函数可能位于另一个存储空间中,实际上它们是相同的。正如我前面提到的,它既不安全,也不合法。我在问题中添加了x86标签。它只需要在x86架构上使用gcc和MSVC。

5 个答案:

答案 0 :(得分:9)

你没有,你不能。指针到成员函数不是指针(对象,即对于任何类型T*它们都不是T)。它们不一定,甚至实际上也不适合void*

你对void*唯一了解的是它足以容纳任何对象指针。而已。它甚至与普通的自由函数指针无关。在紧缩中,您可以将void指针的自由函数模拟定义为typedef void(*voidf)();,但这仅适用于自由函数。对于指向成员的函数,没有一般性的东西,因为PTMF的精确实现取决于类的性质(简单,多态,虚拟派生,......)。

答案 1 :(得分:2)

使用x86程序集:

在MSVC上:

__asm{
    mov eax, (Foo::Bar);
    mov address, eax;
}

在g ++上:

__asm__ __volatile__("mov %1, %0":"=r"(address):"r"(&Foo::Bar));

答案 2 :(得分:0)

您无法将函数指针强制转换为void指针。查看C++ faq了解更多详情

答案 3 :(得分:0)

您不能将对象函数(“方法”)的地址强制转换为全局“普通指针”。

为了被调用,方法需要引用对象。

如果你有这个:

class MyClass
{
  void Hello(char* AName) { ... }
}

void main()
{
  MyClass MyObject = new MyClass();
  MyObject->Hello("World");
  delete MyObject;
}

该程序在内部执行以下操作:

void main()
{
  MyClass MyObject = new MyClass();
  Hello(MyObject, "World");
  delete MyObject;
}

你为什么要这样做?

您需要方法的地址,因为是问题的解决方案

你的编程问题是什么? 也许还有另一种解决方法。

答案 4 :(得分:0)

是的,您可以使用纯C ++,但在许多情况下只是为了好玩或检查指针的好坏。但是它可以用来为程序添加更多动态行为。

struct A {
    void f1() {
        printf("f1:\n");
    }

    void f2() {
        printf("f2:\n");
    }
};

A a;

char f[sizeof(&A::f1)];
{
    void (A::*i)(void) = &A::f1;
    memcpy(f, &i, sizeof(f));
    (a.*i)();
}
(a.*(*(void (A::**)(void)) &f))();

{
    void (A::*i)(void) = &A::f2;
    memcpy(f, &i, sizeof(f));
    (a.*i)();
}
(a.*(*(void (A::**)(void)) &f))();