获取成员函数的内存地址?

时间:2011-11-14 12:06:50

标签: c++ visual-c++ memory-address member-functions

如何在C ++中获取成员函数的绝对地址? (我需要这个来进行捶击。)

成员函数指针不起作用,因为我无法将它们转换为绝对地址(void *) - 我需要知道内存中实际函数的地址,而不仅仅是相对于类型的地址

4 个答案:

答案 0 :(得分:25)

存在一种语法来获取MSVC中的成员函数的地址(从MSVC 2005 IMHO开始)。但这很棘手。而且,所获得的指针不可能通过传统方式转换为其他指针类型。尽管如此,仍然有办法做到这一点。

以下是示例:

// class declaration
class MyClass
{
public:
    void Func();
    void Func(int a, int b);
};

// get the pointer to the member function
void (__thiscall MyClass::* pFunc)(int, int) = &MyClass::Func;

// naive pointer cast
void* pPtr = (void*) pFunc; // oops! this doesn't compile!

// another try
void* pPtr = reinterpret_cast<void*>(pFunc); // Damn! Still doesn't compile (why?!)

// tricky cast
void* pPtr = (void*&) pFunc; // this works

即使使用reinterpret_cast,传统演员也不起作用的事实可能意味着MS不会非常强烈推荐这种演员。

尽管如此,你可以这样做。当然这是所有依赖于实现的,你必须知道适当的调用约定来进行thunking +具有适当的汇编技能。

答案 1 :(得分:4)

试试这个。应该让你投入任何东西:)

template<typename OUT, typename IN>
OUT ForceCast( IN in )
{
    union
    {
        IN  in;
        OUT out;
    }
    u = { in };

    return u.out;
};

然后

void* member_address = ForceCast<void*>(&SomeClass::SomeMethod);

答案 2 :(得分:2)

  

默认情况下,C ++成员函数使用__thiscall调用   惯例。为了绕道一个成员的功能,两个蹦床   并且绕行必须具有完全相同的调用约定   目标函数。不幸的是,VC编译器不支持   __这个呼叫,所以创建合法的绕道和蹦床功能的唯一方法是让他们成为“绕道”班的班级成员。

     

此外,C ++不支持将指针转换为成员   函数到任意指针。 获取原始指针,地址   必须将成员函数移动到临时成员函数中   指针,然后通过获取它的地址,然后取消引用它。   幸运的是,编译器将优化代码以删除额外的代码   指针操作。

来自Microsoft Detour库的

。他们处理代码注入并讨论获取非虚拟成员函数的地址。当然它是特定于编译器实现的东西。

您可以在http://research.microsoft.com/en-us/downloads/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/default.aspx

找到图书馆

答案 3 :(得分:0)

对于仍在寻找获取函数的内存地址(而不是跳转)的答案的人,这是我的解决方案:

UINT32 RelativityToTrampoline = *(UINT32*)((UINT64)&Func + 1);
UINT64 RealFuncAddr = (UINT64)&Func + RelativityToTrampoline + 5;