Приведение GetProcAddress возвращает указатель в переполнении стека

GetProcAddress возвращает указатель на функцию.
Предположим, мы получили адрес функции Beep (ее объявление можно найти в WinBase.h (при включении Windows.h))

BOOL WINAPI Beep(
_In_  DWORD dwFreq,
_In_  DWORD dwDuration
);

тогда классический код может выглядеть примерно так

typedef BOOL(__stdcall *pbeep)(DWORD , DWORD );
pbeep beep = NULL;
FARPROC fptr = GetProcAddress(Hnd,"Beep");
beep = reinterpret_cast<pbeep>(fptr);
if( beep != NULL ) {
beep( 440, 1200 ); //this generates a beep for 1.2 secs...
}

Все выглядит хорошо и работает.
Мой вопрос:

Есть ли способ избежать объявления typedef, учитывая, что компилятор «каким-то образом» может получить «информацию» указателя функции из уже включенного объявления Beep () из WinBase.h.
Моя цель состоит в том, чтобы как-то повторно использовать информацию (return / parameters / etc), уже содержащуюся в уже включенном файле .h, где объявлена ​​функция Beep (), без необходимости вручную повторять всю эту информацию в typedef. когда это делается для одной функции, это нормально, но когда число функций увеличивается, typedef — это действительно боль и большой источник ошибок.
Это может быть сделано?

редактировать;
Я скоро переезжаю на VS 2013, но до сих пор использую VS2008
тогда идея делает это без C ++ 11

1

Решение

Вы можете сделать функцию для этого в C ++ 11 (или, возможно, в C ++ 03, если вы можете заставить Boost.Typeof выполнять ваши ставки):

template<typename F>
F GetKnownProcAddress(HMODULE hmod, const char *name, F) {
auto proc = reinterpret_cast<F>(GetProcAddress(hmod, name));
if (!proc) {/*throw or something*/}
return proc;
}

int main() {
auto beep = GetKnownProcAddress(Hnd, "Beep", Beep);
}

Если вы хотите использовать макрос, вы можете пойти еще дальше:

//where GetKnownProcAddressImpl is the above; also consider the usual STRINGIFY
#define GetKnownProcAddress(hmod, func) GetKnownProcAddressImpl(hmod, #func, func);
auto beep = GetKnownAddressProc(Hnd, Beep);
4

Другие решения

#include <windows.h>

int main()
{
decltype(Beep)* beep = (decltype(Beep)*)GetProcAddress(GetModuleHandle("Kernel32.dll"), "Beep");
beep(440, 1200);
}
2

В C ++ 11 вы можете написать

decltype (&Beep) beep_ptr = reinterpret_cast<decltype (&Beep)>GetProcAddress(Hnd,"Beep");

Но я не понимаю, зачем вам это делать — если у вас уже есть указатель на функцию, зачем загружать ее вручную?

1

BOOL (__stdcall *beep)(DWORD, DWORD); // beep - pointer to function with parameters (DWORD, DWORD) and result of type bool
(FARPROC)beep = GetProcAddress(Hnd,"Beep");
if( beep != NULL ) {
beep( 440, 1200 ); //this generates a beep for 1.2 secs...
}
0

Или попробуйте: —

typedef BOOL (*pbeep)(DWORD, DWORD);
FARPROC fptr = GetProcAddress(Hnd,"Beep");
((pbeep)fptr)( 440, 1200);
0
По вопросам рекламы [email protected]