Skip to content

Commit c66eba3

Browse files
committed
Use external library loader
1 parent f5dec89 commit c66eba3

File tree

5 files changed

+40
-49
lines changed

5 files changed

+40
-49
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "dynalo"]
2+
path = gm_dotnet_native/external_includes/dynalo
3+
url = https://github.com/Stat1cV01D/dynalo.git

gm_dotnet_native/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ add_library(gm_dotnet_native SHARED src/gm_dotnet.cpp dotnethelper-src/cleanup_f
2525
add_library(dotnethelper SHARED dotnethelper-src/dotnethelper.cpp dotnethelper-src/cleanup_function_type.h
2626
dotnethelper-src/LuaAPIExposure.h dotnethelper-src/LuaAPIExposure.cpp)
2727
#Set up external include libraries
28-
include_directories ("${EXTERNAL_INCLUDES_PATH}")
28+
include_directories ("${EXTERNAL_INCLUDES_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}")
29+
add_subdirectory ("${EXTERNAL_INCLUDES_PATH}/dynalo")
30+
target_link_libraries(gm_dotnet_native PUBLIC dynalo)
31+
target_link_libraries(dotnethelper PUBLIC dynalo)
2932
#Set up compile definitions
3033
target_compile_definitions(gm_dotnet_native PUBLIC SEM_VERSION="${SEM_VERSION}")
3134
target_compile_definitions(dotnethelper PUBLIC SEM_VERSION="${SEM_VERSION}")

gm_dotnet_native/dotnethelper-src/dotnethelper.cpp

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <string>
1111
#include <fstream>
1212
#include <filesystem>
13+
#include <dynalo/dynalo.hpp>
1314
#ifdef WIN32
1415
#include <Windows.h>
1516
#else
@@ -51,23 +52,13 @@ managed_main_fn managed_main = nullptr;
5152

5253
const std::filesystem::path lua_bin_folder = _T("garrysmod/lua/bin");
5354
const std::filesystem::path hostfxr_path = (lua_bin_folder / _T("dotnet/host/fxr") / NET_CORE_VERSION).make_preferred();
54-
#ifdef WIN32
55-
HMODULE hostfxr_library_handle = LoadLibraryW((hostfxr_path / _T("hostfxr.dll")).c_str());
56-
#elif __APPLE__
57-
void* hostfxr_library_handle = dlopen((hostfxr_path / "libhostfxr.dylib").c_str(), RTLD_LAZY | RTLD_LOCAL);
58-
#elif __gnu_linux__
59-
void* hostfxr_library_handle = dlopen((hostfxr_path / "libhostfxr.so").c_str(), RTLD_LAZY);
60-
#endif
55+
56+
const dynalo::library hostfxr_library(hostfxr_path / dynalo::to_native_name("hostfxr"));
6157

6258
template<typename T>
63-
bool LoadFunction(const char* function_name, T& out_func)
59+
void load_hostfxr_function(const char* function_name, T& out_func)
6460
{
65-
#ifdef WIN32
66-
out_func = reinterpret_cast<T>(GetProcAddress(hostfxr_library_handle, function_name));
67-
#else
68-
out_func = reinterpret_cast<T>(dlsym(hostfxr_library_handle, function_name));
69-
#endif
70-
return (out_func != nullptr);
61+
out_func = hostfxr_library.get_function<std::remove_pointer_t<T>>(function_name);
7162
}
7263
hostfxr_initialize_for_dotnet_command_line_fn hostfxr_initialize_for_dotnet_command_line = nullptr;
7364
hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate = nullptr;
@@ -161,11 +152,15 @@ extern "C" DYNAMIC_EXPORT cleanup_function_fn InitNetRuntime(GarrysMod::Lua::ILu
161152

162153
if(managed_main == nullptr)
163154
{
164-
if(!(LoadFunction("hostfxr_initialize_for_dotnet_command_line", hostfxr_initialize_for_dotnet_command_line)
165-
&& LoadFunction("hostfxr_get_runtime_delegate", hostfxr_get_runtime_delegate)
166-
&& LoadFunction("hostfxr_set_error_writer", hostfxr_set_error_writer)))
155+
try
156+
{
157+
load_hostfxr_function("hostfxr_initialize_for_dotnet_command_line", hostfxr_initialize_for_dotnet_command_line);
158+
load_hostfxr_function("hostfxr_get_runtime_delegate", hostfxr_get_runtime_delegate);
159+
load_hostfxr_function("hostfxr_set_error_writer", hostfxr_set_error_writer);
160+
}
161+
catch (std::runtime_error ex)
167162
{
168-
error_log_file << "Unable to load hostfxr library" << std::endl;
163+
error_log_file << "Unable to load hostfxr library: " << ex.what() << std::endl;
169164
return nullptr;
170165
}
171166

Submodule dynalo added at a1adfd9

gm_dotnet_native/src/gm_dotnet.cpp

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,25 @@
1010
#include <dlfcn.h>
1111
#endif // WIN32
1212
#include <string>
13-
#include "../dotnethelper-src/cleanup_function_type.h"
14-
15-
typedef cleanup_function_fn (*InitNetRuntime_fn)(GarrysMod::Lua::ILuaBase* lua);
13+
#include "dotnethelper-src/cleanup_function_type.h"
14+
#include <dynalo/dynalo.hpp>
1615

1716
cleanup_function_fn cleanup_function = nullptr;
1817

18+
const std::filesystem::path lua_bin_folder("garrysmod/lua/bin");
19+
20+
#ifdef __gnu_linux__
21+
const dynalo::library liblinuxhelper(lua_bin_folder / "liblinuxhelper.so");
22+
#endif
23+
24+
const dynalo::library dotnethelper(lua_bin_folder / dynalo::to_native_name("dotnethelper"));
25+
1926
//Invoked by Garry's Mod on module load
2027
GMOD_MODULE_OPEN()
2128
{
22-
const std::filesystem::path lua_bin_folder("garrysmod/lua/bin");
23-
2429
// On Linux, modify SIGSEGV handling
2530
#ifdef __gnu_linux__
26-
void *linux_helper_handle = dlopen((lua_bin_folder / "liblinuxhelper.so").c_str(), RTLD_LAZY);
27-
void (*pointer_to_install_sigsegv)(void);
28-
pointer_to_install_sigsegv = (void(*)())dlsym(linux_helper_handle, "install_sigsegv_handler");
31+
auto pointer_to_install_sigsegv = liblinuxhelper.get_function<void()>("install_sigsegv_handler");
2932
pointer_to_install_sigsegv();
3033
#endif
3134

@@ -36,36 +39,22 @@ GMOD_MODULE_OPEN()
3639
LUA->Call(1, 0);
3740
LUA->Pop(1);
3841

39-
InitNetRuntime_fn InitNetRuntime = nullptr;
40-
const char InitNetRuntime_fn_name[] = "InitNetRuntime";
41-
42-
#ifdef WIN32
43-
HMODULE dotnethelper_handle = LoadLibraryW((lua_bin_folder / "dotnethelper.dll").make_preferred().c_str());
44-
if (dotnethelper_handle != nullptr)
45-
InitNetRuntime = reinterpret_cast<InitNetRuntime_fn>(GetProcAddress(dotnethelper_handle, InitNetRuntime_fn_name));
46-
#elif __APPLE__
47-
void* dotnethelper_handle = dlopen((lua_bin_folder / "libdotnethelper.dylib").c_str(), RTLD_LAZY);
48-
#elif __gnu_linux__
49-
void* dotnethelper_handle = dlopen((lua_bin_folder / "libdotnethelper.so").c_str(), RTLD_LAZY);
50-
#endif
51-
52-
#ifndef WIN32
53-
InitNetRuntime = reinterpret_cast<InitNetRuntime_fn>(dlsym(dotnethelper_handle, InitNetRuntime_fn_name));
54-
#endif
55-
56-
if(InitNetRuntime == nullptr)
42+
try
5743
{
44+
auto InitNetRuntime = dotnethelper.get_function<cleanup_function_fn(GarrysMod::Lua::ILuaBase*)>("InitNetRuntime");
45+
cleanup_function = InitNetRuntime(LUA);
46+
}
47+
catch(std::runtime_error e)
48+
{
49+
auto error_msg = std::string("::error::Unable to load dotnet helper library. ") + e.what();
5850
LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB);
5951
LUA->GetField(-1, "print");
60-
LUA->PushString("::error::Unable to load dotnet helper library.");
52+
LUA->PushString(error_msg.c_str());
6153
LUA->Call(1, 0);
6254
LUA->Pop(1);
63-
6455
return 0;
6556
}
6657

67-
cleanup_function = InitNetRuntime(LUA);
68-
6958
if(cleanup_function == nullptr)
7059
{
7160
LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB);

0 commit comments

Comments
 (0)