Created
May 11, 2015 08:20
-
-
Save r-lyeh-archived/2382135ab89d1e6e99d2 to your computer and use it in GitHub Desktop.
std::function && dll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// [ref] http://stackoverflow.com/questions/15249465/c-dynamically-load-arbitrary-function-from-dll-into-stdfunction | |
template <typename T> | |
struct TypeParser {}; | |
template <typename Ret, typename... Args> | |
struct TypeParser<Ret(Args...)> { | |
static std::function<Ret(Args...)> createFunction(const FARPROC lpfnGetProcessID) { | |
return std::function<Ret(Args...)>(reinterpret_cast<Ret (__stdcall *)(Args...)>(lpfnGetProcessID)); | |
} | |
}; | |
template <typename T> | |
std::function<T> loadDllFunc(const std::string& dllName, const std::string& funcName) { | |
// Load DLL. | |
HINSTANCE hGetProcIDDLL = LoadLibrary(dllName.c_str()); | |
// Check if DLL is loaded. | |
if (hGetProcIDDLL == NULL) { | |
std::cerr << "Could not load DLL \"" << dllName << "\"" << std::endl; | |
exit(EXIT_FAILURE); | |
} | |
// Locate function in DLL. | |
FARPROC lpfnGetProcessID = GetProcAddress(hGetProcIDDLL, funcName.c_str()); | |
// Check if function was located. | |
if (!lpfnGetProcessID) { | |
std::cerr << "Could not locate the function \"" << funcName << "\" in DLL\"" << dllName << "\"" << std::endl; | |
exit(EXIT_FAILURE); | |
} | |
// Create function object from function pointer. | |
return TypeParser<T>::createFunction(lpfnGetProcessID); | |
} | |
/* usage: | |
// test.cc (test.dll) | |
#include <iostream> | |
// Declare function prototypes with "extern C" to prevent name mangling. | |
// Declare functions using __declspec(dllexport) to signify the intent to export. | |
extern "C" { | |
__declspec(dllexport) int __stdcall plusFive(int); | |
__declspec(dllexport) void __stdcall printHello(); | |
} | |
int plusFive(int value) { | |
return value + 5; | |
} | |
void printHello() { | |
std::cout << "Hello!" << std::endl; | |
} | |
// main.cc | |
int main() { | |
auto func1 = loadDllFunc<int(int)>("test.dll", "plusFive"); | |
auto func2 = loadDllFunc<void()>("test.dll", "printHello"); | |
std::cout << "Result of func1: " << func1(1) << std::endl; | |
func2(); | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice one. Thanks!