转换GetProcAddress在C ++中返回指针

时间:2014-02-02 22:50:22

标签: c++ pointers 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声明,因为编译器可以“以某种方式”从WinBase.h中已经包含的Beep()声明中获取函数指针“information”。 我的目标是以某种方式重新使用已经包含在已经包含的.h文件中的信息(返回/参数/等),其中声明了Beep()函数,而不必手动重复typedef上的所有信息。当为一个函数执行它时没关系,但是当函数数量增加时,这些typedef实际上是一个痛苦和错误的重要来源。 可以这样做吗?

编辑; 我很快就会转向VS 2013,但到目前为止仍在使用VS2008 那么这个想法是用C ++ 11

做的

5 个答案:

答案 0 :(得分:4)

你可以在C ++ 11中创建一个函数(或者如果你可以使Boost.Typeof进行出价,可以使用C ++ 03):

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

答案 1 :(得分:2)

#include <windows.h>

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

答案 2 :(得分:1)

在c ++ 11中你可以写

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

但是我不明白你为什么要这样做 - 如果你已经有一个指向函数的指针,为什么要手动加载它?

答案 3 :(得分:0)

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...
}

答案 4 :(得分:0)

或尝试: -

typedef BOOL (*pbeep)(DWORD, DWORD);
FARPROC fptr = GetProcAddress(Hnd,"Beep");
((pbeep)fptr)( 440, 1200);