diff --git a/source/reflect_load_metafunction.h b/source/reflect_load_metafunction.h index bbc8759c8a..ae35778329 100644 --- a/source/reflect_load_metafunction.h +++ b/source/reflect_load_metafunction.h @@ -5,25 +5,24 @@ #include #include "cpp2util.h" -#ifdef _MSC_VER -#define WIN32_LEAN_AND_MEAN -#include +#ifdef _WIN32 +#include #else #include -#endif // _MSC_VER +#endif // _WIN32 namespace cpp2::meta { class dll { public: - dll(std::string_view path) + dll(std::string const& path) { -#ifdef _MSC_VER - handle_ = static_cast(LoadLibraryA(path.data())); +#ifdef _WIN32 + handle_ = static_cast(LoadLibraryA(path.c_str())); #else - handle_ = static_cast(dlopen(path.data(), RTLD_NOW|RTLD_LOCAL)); -#endif // _MSC_VER + handle_ = static_cast(dlopen(path.c_str(), RTLD_NOW|RTLD_LOCAL)); +#endif // _WIN32 // TODO: log if the dll could not be open? } @@ -31,11 +30,11 @@ class dll { if(handle_ == nullptr); return; -#ifdef _MSC_VER - FreeLibrary(static_cast(handle)); +#ifdef _WIN32 + FreeLibrary(static_cast(handle_)); #else dlclose(handle_); -#endif // _MSC_VER +#endif // _WIN32 } // Uncopyable @@ -60,25 +59,31 @@ class dll auto is_open() noexcept -> bool { return handle_ != nullptr; } template - auto get_alias(std::string_view name) noexcept -> T* + auto get_alias(std::string const& name) noexcept -> T* { - void* symbol = nullptr; -#ifdef _MSC_VER - symbol = static_cast(GetProcAddress(static_cast(handle_), name.data())); +#ifdef _WIN32 + auto symbol = GetProcAddress(static_cast(handle_), name.c_str()); #else - symbol = dlsym(handle_, name.data()); + auto symbol = dlsym(handle_, name.c_str()); if(symbol == nullptr) { // Some platforms export with additional underscore, so try that. - auto const us_name = std::string("_") + name.data(); + auto const us_name = "_" + name; symbol = dlsym(handle_, us_name.c_str()); } -#endif // _MSC_VER +#endif // _WIN32 // TODO: log if the symbol is not found? - return reinterpret_cast(symbol); + return function_cast(symbol); } private: void* handle_{nullptr}; + + template + static T function_cast(auto ptr) { + using generic_function_ptr = void (*)(void); + return reinterpret_cast(reinterpret_cast(ptr)); + } + }; @@ -89,6 +94,10 @@ class dll // 'CPPFRONT_METAFUNCTION_LIBRARIES' auto load_metafunction(std::string const& name) -> std::function { + // FIXME: On Windows, using this approach with the system apis not set to utf8, will + // break if a metafunction library contains unicode codepoints in its name, a proper + // way to handle this would be to use _wgetenv and use wchar_t strings for the dll opening + // function auto cpp1_libraries_cstr = std::getenv("CPPFRONT_METAFUNCTION_LIBRARIES"); if (!cpp1_libraries_cstr) { return {}; @@ -103,7 +112,7 @@ auto load_metafunction(std::string const& name) -> std::function(lib_path); + auto lib = std::make_shared(std::string(lib_path)); if(!lib->is_open()) continue;