Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting GetProcAddress returned pointer in C++

GetProcAddress returns a function pointer. Lets suppose we get the address of the function Beep ( its declaration can be found at WinBase.h (when including Windows.h))

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

then the classic code could look something like

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

Everything looks good and works. My question:

Is there any way I can avoid the typedef declaration considering the compiler could "somehow" get the function pointer "information" from the already included Beep() declaration from WinBase.h. My goal is to somehow re-use the info (return/parameters/etc) already contained at the already included .h file where the Beep() function is declared w/o having to manually repeat all of that info on a typedef. when doing it for one function it's ok but when the number of functions grows those typedef are really a pain and a big source of errors. Can that be done?

edit; I'm moving to VS 2013 soon but so far still using VS2008 then the idea is doing this w/o C++11

like image 444
Pat Avatar asked Apr 11 '26 19:04

Pat


1 Answers

You can make a function to do that in C++11 (or possibly C++03 if you can make Boost.Typeof do your bidding):

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

If you're willing to use a macro, you can go one step further:

//where GetKnownProcAddressImpl is the above; also consider the usual STRINGIFY
#define GetKnownProcAddress(hmod, func) GetKnownProcAddressImpl(hmod, #func, func);
auto beep = GetKnownAddressProc(Hnd, Beep);
like image 85
chris Avatar answered Apr 13 '26 08:04

chris



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!