Получить адрес памяти функции-члена? - PullRequest
22 голосов
/ 14 ноября 2011

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

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

Ответы [ 3 ]

25 голосов
/ 14 ноября 2011

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

4 голосов
/ 27 февраля 2016

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

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 голосов
/ 28 августа 2012

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...