1313#ifdef WIN32
1414#include < Windows.h>
1515#else
16+ #include < cstring>
1617#include < dlfcn.h>
1718#include < unistd.h>
1819#endif
1920
2021#ifdef WIN32
21- #define DYNANAMIC_EXPORT _declspec (dllexport)
22+ #define DYNAMIC_EXPORT _declspec (dllexport)
23+ #define __T (x ) L ## x
2224#else
23- #define DYNANAMIC_EXPORT __attribute__ ((visibility(" default" )))
25+ #define DYNAMIC_EXPORT __attribute__ ((visibility(" default" )))
26+ #define __T (x ) x
2427#endif
2528
29+ #define _T (x ) __T(x)
30+
2631typedef int (*managed_delegate_executor_fn)(
2732 lua_State * luaState
2833);
@@ -36,40 +41,37 @@ typedef cleanup_function_fn(*managed_main_fn)(
3641 /* Out Param */ managed_delegate_executor_fn* managed_delegate_executor_ptr
3742 );
3843
44+ using tstring = std::basic_string<char_t >;
45+
3946std::ofstream error_log_file;
4047
4148managed_delegate_executor_fn managed_delegate_executor = nullptr ;
4249
4350managed_main_fn managed_main = nullptr ;
4451
45- std::string hosfxr_path = " garrysmod/lua/bin/dotnet/host/fxr/" + std::string(NET_CORE_VERSION);
52+ const std::filesystem::path lua_bin_folder = _T(" garrysmod/lua/bin" );
53+ const std::filesystem::path hostfxr_path = (lua_bin_folder / _T(" dotnet/host/fxr" ) / NET_CORE_VERSION).make_preferred();
4654#ifdef WIN32
47- void * hostfxr_library_handle = LoadLibraryA((hosfxr_path + " / hostfxr.dll" ).c_str());
55+ HMODULE hostfxr_library_handle = LoadLibraryW((hostfxr_path / _T( " hostfxr.dll" ) ).c_str());
4856#elif __APPLE__
49- void * hostfxr_library_handle = dlopen((hosfxr_path + " / libhostfxr.dylib" ).c_str(), RTLD_LAZY | RTLD_LOCAL);
57+ void * hostfxr_library_handle = dlopen((hostfxr_path / " libhostfxr.dylib" ).c_str(), RTLD_LAZY | RTLD_LOCAL);
5058#elif __gnu_linux__
51- void * hostfxr_library_handle = dlopen((hosfxr_path + " / libhostfxr.so" ).c_str(), RTLD_LAZY);
59+ void * hostfxr_library_handle = dlopen((hostfxr_path / " libhostfxr.so" ).c_str(), RTLD_LAZY);
5260#endif
5361
62+ template <typename T>
63+ bool LoadFunction (const char * function_name, T& out_func)
64+ {
5465#ifdef WIN32
55- hostfxr_initialize_for_dotnet_command_line_fn hostfxr_initialize_for_dotnet_command_line =
56- reinterpret_cast <hostfxr_initialize_for_dotnet_command_line_fn>(GetProcAddress(static_cast <HMODULE>(hostfxr_library_handle),
57- " hostfxr_initialize_for_dotnet_command_line" ));
58- hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate =
59- reinterpret_cast <hostfxr_get_runtime_delegate_fn>(GetProcAddress(static_cast <HMODULE>(hostfxr_library_handle),
60- " hostfxr_get_runtime_delegate" ));
61-
62- hostfxr_set_error_writer_fn hostfxr_set_error_writer =
63- reinterpret_cast <hostfxr_set_error_writer_fn>(GetProcAddress(static_cast <HMODULE>(hostfxr_library_handle),
64- " hostfxr_set_error_writer" ));
66+ out_func = reinterpret_cast <T>(GetProcAddress (hostfxr_library_handle, function_name));
6567#else
66- hostfxr_initialize_for_dotnet_command_line_fn hostfxr_initialize_for_dotnet_command_line =
67- reinterpret_cast <hostfxr_initialize_for_dotnet_command_line_fn>(dlsym(hostfxr_library_handle, " hostfxr_initialize_for_dotnet_command_line" ));
68- hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate =
69- reinterpret_cast <hostfxr_get_runtime_delegate_fn>(dlsym(hostfxr_library_handle, " hostfxr_get_runtime_delegate" ));
70- hostfxr_set_error_writer_fn hostfxr_set_error_writer =
71- reinterpret_cast <hostfxr_set_error_writer_fn>(dlsym(hostfxr_library_handle, " hostfxr_set_error_writer" ));
68+ out_func = reinterpret_cast <T>(dlsym (hostfxr_library_handle, function_name));
7269#endif
70+ return (out_func != nullptr );
71+ }
72+ hostfxr_initialize_for_dotnet_command_line_fn hostfxr_initialize_for_dotnet_command_line = nullptr ;
73+ hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate = nullptr ;
74+ hostfxr_set_error_writer_fn hostfxr_set_error_writer = nullptr ;
7375
7476void HOSTFXR_CALLTYPE dotnet_error_writer (const char_t *message)
7577{
@@ -150,7 +152,7 @@ void * params_to_managed_code[] = {
150152 reinterpret_cast <void *>(export_push_c_function_safe)
151153};
152154
153- extern " C" DYNANAMIC_EXPORT cleanup_function_fn InitNetRuntime (GarrysMod::Lua::ILuaBase* lua)
155+ extern " C" DYNAMIC_EXPORT cleanup_function_fn InitNetRuntime (GarrysMod::Lua::ILuaBase* lua)
154156{
155157 if (!error_log_file.is_open ())
156158 {
@@ -159,7 +161,9 @@ extern "C" DYNANAMIC_EXPORT cleanup_function_fn InitNetRuntime(GarrysMod::Lua::I
159161
160162 if (managed_main == nullptr )
161163 {
162- if (hostfxr_initialize_for_dotnet_command_line == nullptr || hostfxr_get_runtime_delegate == nullptr || hostfxr_set_error_writer == nullptr )
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)))
163167 {
164168 error_log_file << " Unable to load hostfxr library" << std::endl;
165169 return nullptr ;
@@ -169,27 +173,24 @@ extern "C" DYNANAMIC_EXPORT cleanup_function_fn InitNetRuntime(GarrysMod::Lua::I
169173
170174 hostfxr_set_error_writer (dotnet_error_writer);
171175
176+ const auto gmodnet_dll_relative_path = lua_bin_folder / _T (" gmodnet/GmodNET.dll" );
177+ const auto dotnet_root_path = (std::filesystem::current_path () / lua_bin_folder / " dotnet" ).make_preferred ();
178+
179+ const char_t * dotnet_args[] = {_T (" exec" ), gmodnet_dll_relative_path.c_str ()};
180+
181+ tstring game_exe_path (301 , _T (' \0 ' ));
172182#ifdef WIN32
173- const char_t * dotnet_args[ 2 ] = { L" exec " , L" garrysmod/lua/bin/gmodnet/GmodNET.dll " } ;
183+ GetModuleFileNameW ( nullptr , game_exe_path. data (), static_cast <DWORD>(game_exe_path. size ()) - 1 ) ;
174184#else
175- const char_t * dotnet_args[ 2 ] = { " exec " , " garrysmod/lua/bin/gmodnet/GmodNET.dll " } ;
185+ readlink ( " /proc/self/exe " , game_exe_path. data (), game_exe_path. size () - 1 ) ;
176186#endif
177187 hostfxr_initialize_parameters dotnet_runtime_params;
178188 dotnet_runtime_params.size = sizeof (hostfxr_initialize_parameters);
179- #ifdef WIN32
180- char_t game_exe_path[301 ];
181- int game_exe_path_len = GetModuleFileNameW (nullptr , game_exe_path, 300 );
182- #else
183- char game_exe_path[301 ];
184- int game_exe_path_len = readlink (" /proc/self/exe" , game_exe_path, 300 );
185- game_exe_path[game_exe_path_len] = ' \0 ' ;
186- #endif
187- dotnet_runtime_params.host_path = game_exe_path;
189+ dotnet_runtime_params.host_path = game_exe_path.c_str ();
190+ dotnet_runtime_params.dotnet_root = dotnet_root_path.c_str ();
188191
189- std::filesystem::path dotnet_root_path = std::filesystem::current_path () / " garrysmod" / " lua" / " bin" / " dotnet" ;
190- dotnet_runtime_params.dotnet_root = dotnet_root_path.native ().c_str ();
191-
192- int init_success_code = hostfxr_initialize_for_dotnet_command_line (2 , dotnet_args, &dotnet_runtime_params, &runtime_environment_handle);
192+ int init_success_code = hostfxr_initialize_for_dotnet_command_line (static_cast <int >(std::size (dotnet_args)), dotnet_args,
193+ &dotnet_runtime_params, &runtime_environment_handle);
193194 if (init_success_code != 0 )
194195 {
195196 error_log_file << " Unable to initialize dotnet runtime. Error code: " << init_success_code << std::endl;
@@ -212,13 +213,9 @@ extern "C" DYNANAMIC_EXPORT cleanup_function_fn InitNetRuntime(GarrysMod::Lua::I
212213 error_log_file << " get_function_pointer is null" << std::endl;
213214 return nullptr ;
214215 }
215- #ifdef WIN32
216- int get_managed_main_success_code = get_function_pointer (L" GmodNET.Startup, GmodNET" , L" Main" , UNMANAGEDCALLERSONLY_METHOD,
217- nullptr , nullptr , reinterpret_cast <void **>(&managed_main));
218- #else
219- int get_managed_main_success_code = get_function_pointer (" GmodNET.Startup, GmodNET" , " Main" , UNMANAGEDCALLERSONLY_METHOD,
216+
217+ int get_managed_main_success_code = get_function_pointer (_T (" GmodNET.Startup, GmodNET" ), _T (" Main" ), UNMANAGEDCALLERSONLY_METHOD,
220218 nullptr , nullptr , reinterpret_cast <void **>(&managed_main));
221- #endif
222219 if (get_managed_main_success_code != 0 )
223220 {
224221 error_log_file << " Unable to load managed entry point: Error code: " << get_managed_main_success_code << std::endl;
@@ -230,7 +227,8 @@ extern "C" DYNANAMIC_EXPORT cleanup_function_fn InitNetRuntime(GarrysMod::Lua::I
230227 return nullptr ;
231228 }
232229 }
233- return managed_main (lua, std::string (SEM_VERSION).c_str (), std::string (SEM_VERSION).length (), params_to_managed_code,
230+
231+ return managed_main (lua, SEM_VERSION, static_cast <int >(std::strlen (SEM_VERSION)), params_to_managed_code,
234232 native_delegate_executor, &managed_delegate_executor);
235233}
236234
0 commit comments