Подтвердить что ты не робот

Получить адрес памяти функции-члена?

Как получить абсолютный адрес функции-члена в С++? (Мне нужно это для thunking.)

Указатели функции-функции не работают, потому что я не могу преобразовать их в абсолютные адреса (void *). Мне нужно знать адрес фактической функции в памяти, а не просто адрес по отношению к типу.

4b9b3361

Ответ 1

Существует синтаксис для получения адреса функции-члена в 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 +, чтобы иметь соответствующие навыки ассемблера.

Ответ 2

попробуйте это. должен позволять вам что-то притворяться:)

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);

Ответ 3

По умолчанию члены-члены С++ используют вызов __thiscall условность. Для того, чтобы объединить функцию-член, оба батута и обход должен иметь точно такое же соглашение о вызове, что и целевой функции. К сожалению, компилятор VC не поддерживает __thiscall, поэтому единственный способ создать законные функции объезда и батута - сделать их классными членами класса "обход".

Кроме того, С++ не поддерживает преобразование указателя в член функция к произвольному указателю. Чтобы получить необработанный указатель, адрес функции-члена должны быть перемещены во временную функцию-член указатель, затем передается, беря его адрес, затем де-ссылку на него.К счастью, компилятор оптимизирует код для удаления дополнительных операции указателя.

из библиотеки Microsoft Detour. Они имеют дело с инъекцией кода и обсуждают получение адреса невируальных функций-членов. Конечно, это специфический материал для реализации компилятора.

вы можете найти библиотеку здесь http://research.microsoft.com/en-us/downloads/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/default.aspx