#include "gtkloader.h" extern "C" { #include "gtk-imports.h" } #include #ifdef _WIN32 #include #include #endif void GtkLoader::loadLibraryWin64(const char *lib, void **handle) { #ifdef _WIN32 #define DIR "C:\\devel\\yellownotes\\gtk3\\bin" HMODULE dll = nullptr; std::string dir = DIR; *handle = nullptr; auto mklibname = [](const char *libname) { std::string dll; dll = std::string(DIR) + "\\" + libname + ".dll"; return dll; }; std::string library; library = mklibname(lib); char *cwd = _getcwd(NULL, 0); if (cwd == nullptr) { throw std::string("Cannot get current working directory"); } _chdir(dir.c_str()); dll = LoadLibraryA(library.c_str()); _chdir(cwd); free(cwd); if (dll == nullptr) { throw std::string("Cannot load library '") + lib + "'"; } *handle = reinterpret_cast(dll); #endif } void GtkLoader::loadFunctionWin64(const char *func, void **func_ptr) { #ifdef _WIN32 FARPROC fp = nullptr; std::list::const_iterator it = library_handles.begin(); while (fp == nullptr && it != library_handles.end()) { HMODULE handle = reinterpret_cast(*it); fp = GetProcAddress(handle, func); it++; } *func_ptr = reinterpret_cast(fp); if (fp == nullptr) { throw std::string("Cannot load function '") + func; } #endif } void GtkLoader::dlopen() { if (library_handles.size() == 0) { #ifdef _WIN32 const char *libs[] = { "gobject-2.0-0", "gtk-3-vs17", "glib-2.0-0", "gio-2.0-0", NULL }; int i; for(i = 0; libs[i] != NULL; i++) { void *lib; loadLibraryWin64(libs[i], &lib); if (lib) { library_handles.push_back(lib); } } #endif } } void GtkLoader::loadFunction(const char *func, void **func_ptr) { #ifdef _WIN32 loadFunctionWin64(func, func_ptr); #endif } static void loader(const char *func, void **func_ptr, void *user_data) { GtkLoader *l = reinterpret_cast(user_data); l->loadFunction(func, func_ptr); } void GtkLoader::loadGtk() { dlopen(); loadGtkFunctions(loader, this); } GtkLoader::GtkLoader() { }