View Single Post
  #26  
Old 04-14-2018, 08:39
bugficks bugficks is offline
Friend
 
Join Date: Apr 2018
Posts: 8
Rept. Given: 0
Rept. Rcvd 0 Times in 0 Posts
Thanks Given: 3
Thanks Rcvd at 14 Times in 8 Posts
bugficks Reputation: 0
just for the fun of it, a c++14 version

PHP Code:
#include <string>
#include <memory>
#include <map>
#include <system_error>

template <typename F, typename... ArgTypes>
auto DynCallT(LPCTSTR libName, LPCSTR funcName, ArgTypes... args)
{
    
using tstring = std::basic_string<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR>>;
    
using lib_ptr = std::shared_ptr<std::remove_pointer_t<const HMODULE>>;
    
using lib_map = std::map<const tstring, lib_ptr>;

    static 
lib_map libMap;

    
HMODULE h = nullptr;
    const 
auto &l = libMap.find(libName);
    if(
l != libMap.end())
        
h = l->second.get();
    else if((
h = ::LoadLibrary(libName)) != nullptr)
        
libMap[libName] = lib_ptr(h, ::FreeLibrary);
    else
        throw 
std::system_error(std::make_error_code(std::errc::invalid_argument));

    
F f = reinterpret_cast<F>(::GetProcAddress(h, funcName));
    if(!
f)
        throw 
std::system_error(std::make_error_code(std::errc::function_not_supported));

    return 
f(args...);
} 
usage:
PHP Code:
    // using 'decltype' when you have a prototype 
    
auto r = DynCallT<decltype(&MessageBoxA)>(_T("user32"), "MessageBoxA", nullptr, "123", "321", 0);

    
// or using func decl as template arg
    
auto tc1 = DynCallT<DWORD(WINAPI*)()>(_T("kernel32"), "GetTickCount");

    
// using "i dont give a shit" decl :)
    
auto tc2 = DynCallT<void*(WINAPI*)(...)>(_T("kernel32"), "GetTickCount", 1, "asd");

    
void WINAPI blub(DWORD);
    
DynCallT<decltype(&blub)>(_T("kernel32"), "Sleep", 0); 
Reply With Quote
The Following 3 Users Say Thank You to bugficks For This Useful Post:
niculaita (04-14-2018), tonyweb (05-09-2018)