Skip to content

Fix windows side of dll loading code #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 30 additions & 21 deletions source/reflect_load_metafunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,36 @@
#include <utility>
#include "cpp2util.h"

#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef _WIN32
#include <libloaderapi.h>
#else
#include <dlfcn.h>
#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<void*>(LoadLibraryA(path.data()));
#ifdef _WIN32
handle_ = static_cast<void*>(LoadLibraryA(path.c_str()));
#else
handle_ = static_cast<void*>(dlopen(path.data(), RTLD_NOW|RTLD_LOCAL));
#endif // _MSC_VER
handle_ = static_cast<void*>(dlopen(path.c_str(), RTLD_NOW|RTLD_LOCAL));
#endif // _WIN32
// TODO: log if the dll could not be open?
}

~dll() noexcept
{
if(handle_ == nullptr);
return;
#ifdef _MSC_VER
FreeLibrary(static_cast<HMODULE>(handle));
#ifdef _WIN32
FreeLibrary(static_cast<HMODULE>(handle_));
#else
dlclose(handle_);
#endif // _MSC_VER
#endif // _WIN32
}

// Uncopyable
Expand All @@ -60,25 +59,31 @@ class dll
auto is_open() noexcept -> bool { return handle_ != nullptr; }

template<typename T>
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<void*>(GetProcAddress(static_cast<HMODULE>(handle_), name.data()));
#ifdef _WIN32
auto symbol = GetProcAddress(static_cast<HMODULE>(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<T*>(symbol);
return function_cast<T*>(symbol);
}
private:
void* handle_{nullptr};

template<typename T>
static T function_cast(auto ptr) {
using generic_function_ptr = void (*)(void);
return reinterpret_cast<T>(reinterpret_cast<generic_function_ptr>(ptr));
}

};


Expand All @@ -89,6 +94,10 @@ class dll
// 'CPPFRONT_METAFUNCTION_LIBRARIES'
auto load_metafunction(std::string const& name) -> std::function<void(type_declaration&)>
{
// 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 {};
Expand All @@ -103,7 +112,7 @@ auto load_metafunction(std::string const& name) -> std::function<void(type_decla
auto lib_path = cpp1_libraries.substr(0, colon);
cpp1_libraries.remove_prefix(lib_path.size() + unsigned(colon != lib_path.npos));

auto lib = std::make_shared<dll>(lib_path);
auto lib = std::make_shared<dll>(std::string(lib_path));
if(!lib->is_open())
continue;

Expand Down