В чем разница между двумя приведениями ниже (без ранения):
#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);
Когда ты говоришь
&reinterpret_cast<void*&>(OriginalFunction)
вы берете адрес локальной переменной, которая не то, что вы хотите, потому что она исчезнет, когда DetourFunction
выйдет.
T& OriginalFunction
. Однако, это все еще не объясняет, почему приведение к void**
делает его неудачным.
OriginalFunction
является void**
а затем пытаетесь разыменовать его, вы интерпретируете адрес функции (который, вероятно, является адресом ее первой инструкции ) как void*
, который не является то, что ты хочешь. Я думаю, что Detours ожидает получить адрес переменной, указывающей на функцию, а не адрес самой функции, приведенной к void**
.
reinterpret_cast
что-то для ссылки? Не знал этого. Я предполагаю, что это просто игнорирует справочную часть.