Разница между приведением к переменной & (void * &) и переменной (void **)

0

В чем разница между двумя приведениями ниже (без ранения):

#include <iostream>

void Foo(){}

int main()
{
    //reinterpret_cast<void*>(Foo)<<"\n";             //0x4014e0   
    std::cout<<reinterpret_cast<void**>(Foo)<<"\n"; //0x4014e0
    std::cout<<&reinterpret_cast<void*&>(Foo)<<"\n";//0x4014e0
}

Они оба печатают то же самое значение. Я не могу понять разницу. Однако это имеет значение в следующем фрагменте:

template<typename U>
void DetourFunction(void** OriginalFunction, U HookFunction)
{
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(OriginalFunction, reinterpret_cast<void*>(HookFunction));
    DetourTransactionCommit();
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
}

int main()
{
    DetourFunction(reinterpret_cast<void**>(Foo), MyAddress); //doesn't work & crashes
    DetourFunction(&reinterpret_cast<void*&>(Foo), MyAddress); //works & does not crash
}

Причина, по которой я спрашиваю, заключается в том, что я пытался создать шаблон таким образом:

template<typename T, typename U>
void DetourFunction(T OriginalFunction, U HookFunction)
{
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&reinterpret_cast<void*&>(OriginalFunction), reinterpret_cast<void*>(HookFunction));
    DetourTransactionCommit();
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
}

int main()
{
    DetourFunction(Foo, MyAddress); //seems to be equivalent to reinterpret_cast<void**>(); Crashes
}

Итак, в чем же разница между двумя приведениями и как я могу настроить свою функцию так, чтобы я мог сделать следующее?

DetourFunction(SomeFunc, SomeOtherFunc);
  • 0
    Вы можете reinterpret_cast что-то для ссылки? Не знал этого. Я предполагаю, что это просто игнорирует справочную часть.
  • 0
    @user2357112: user2357112: Не уверен, что вы подразумеваете под "игнорированием ссылочной части" - ссылочная часть на самом деле имеет очень большое значение в результате.
Показать ещё 4 комментария
Теги:
casting

1 ответ

1
Лучший ответ

Когда ты говоришь

&reinterpret_cast<void*&>(OriginalFunction)

вы берете адрес локальной переменной, которая не то, что вы хотите, потому что она исчезнет, когда DetourFunction выйдет.

  • 0
    ДА!! Этот! В заключение. Через 3 часа Вы правы, я изменил это, и это работает. Мне пришлось сделать шаблон T& OriginalFunction . Однако, это все еще не объясняет, почему приведение к void** делает его неудачным.
  • 0
    @CantChooseUsernames: происходит сбой, потому что когда вы притворяетесь, что OriginalFunction является void** а затем пытаетесь разыменовать его, вы интерпретируете адрес функции (который, вероятно, является адресом ее первой инструкции ) как void* , который не является то, что ты хочешь. Я думаю, что Detours ожидает получить адрес переменной, указывающей на функцию, а не адрес самой функции, приведенной к void** .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню