diff --git a/BeefSpace.toml b/BeefSpace.toml index e243759..9b79ee0 100644 --- a/BeefSpace.toml +++ b/BeefSpace.toml @@ -1,6 +1,6 @@ FileVersion = 1 -Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, DirectXTK = {Path = "GlitchyEngine/vendor/DirectXTK/DirectXTK-beef"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}} -WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "DirectXTK", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon"]} +Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}} +WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon"]} [Workspace] StartupProject = "GlitchyEditor" diff --git a/GlitchyEditor/BeefProj.toml b/GlitchyEditor/BeefProj.toml index 964e7e5..b88c96e 100644 --- a/GlitchyEditor/BeefProj.toml +++ b/GlitchyEditor/BeefProj.toml @@ -3,5 +3,4 @@ Dependencies = {corlib = "*", GlitchLog = "*", GlitchyEngine = "*"} [Project] Name = "GlitchyEditor" -TargetType = "BeefGUIApplication" StartupObject = "GlitchyEngine.Program" diff --git a/GlitchyEditor/src/Editor.bf b/GlitchyEditor/src/Editor.bf index 27027ca..e9ad866 100644 --- a/GlitchyEditor/src/Editor.bf +++ b/GlitchyEditor/src/Editor.bf @@ -4,6 +4,7 @@ using System; using System.Collections; using GlitchyEngine.Collections; using GlitchyEditor.EditWindows; +using GlitchyEngineHelper; namespace GlitchyEditor { @@ -29,6 +30,14 @@ namespace GlitchyEditor /// Creates a new editor for the given world public this(Scene scene) { + String str = @"D:\Development\Projects\Beef\GlitchyEngine\build\Debug_Win64\GlitchyEditor\"; + + char16* ptr = str.ToScopedNativeWChar!(); + + DotNetRuntime.Init(); + + DotNetRuntime.TestRunDotNet(1, &ptr); + _scene = scene; _ecsWorld = _scene.[Friend]_ecsWorld; diff --git a/GlitchyEngineHelper/BeefProj.toml b/GlitchyEngineHelper/BeefProj.toml index 1f97ac5..8c18bb1 100644 --- a/GlitchyEngineHelper/BeefProj.toml +++ b/GlitchyEngineHelper/BeefProj.toml @@ -9,5 +9,5 @@ StartupObject = "GlitchyEngineHelper.Program" [Configs.Debug.Win64] BuildCommandsOnCompile = "IfFilesChanged" BuildCommandsOnRun = "IfFilesChanged" -LibPaths = ["$(ProjectDir)/out/build/x64-debug/GlitchyEngineHelper.lib"] -PostBuildCmds = ["$(ProjectDir)\\..\\bin\\vscmake.bat x64 $(ProjectDir) x64-debug"] +LibPaths = ["$(ProjectDir)/out/build/x64-debug/GlitchyEngineHelper.lib", "D:\\Development\\Projects\\Beef\\GlitchyEngine\\GlitchyEngineHelper\\vendor\\dotnethost\\nethost.lib"] +PreBuildCmds = ["$(ProjectDir)\\..\\bin\\vscmake.bat x64 $(ProjectDir) x64-debug", "CopyToDependents(\"$(ProjectDir)/out/build/x64-debug/*.dll\")"] diff --git a/GlitchyEngineHelper/CMakeLists.txt b/GlitchyEngineHelper/CMakeLists.txt index decfff2..5478f04 100644 --- a/GlitchyEngineHelper/CMakeLists.txt +++ b/GlitchyEngineHelper/CMakeLists.txt @@ -5,11 +5,38 @@ cmake_minimum_required (VERSION 3.15) project ("GlitchyEngineHelper") -# Add source to this project's executable. -add_library (GlitchyEngineHelper "GlitchyEngineHelper.cpp" "GlitchyEngineHelper.h" "vendor/xxHash/xxhash.c" "vendor/xxHash/xxhash.h" "vendor/DirectXTK/Src/DDSTextureLoader.cpp") +# Nethost: -include_directories("vendor/DirectXTK/Inc") +# Directory where the files for hosting a dotnet enviroment are located +SET(DOTNET_HOST_DIR "vendor/dotnethost") + +# todo: Find out how to handle this on other platforms +# target_link_libraries(GlitchyEngineHelper "vendor/dotnethost/nethost.lib") + +add_library(NetHost OBJECT IMPORTED) +set_target_properties(NetHost PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/vendor/dotnethost/nethost.lib) +set_property(TARGET NetHost PROPERTY IMPORTED_OBJECTS ${CMAKE_SOURCE_DIR}/vendor/dotnethost/nethost.lib) + +# Copy nethost.dll to output directory +configure_file("${DOTNET_HOST_DIR}/nethost.dll" "${CMAKE_CURRENT_BINARY_DIR}/nethost.dll" COPYONLY) + +# GlitchyEngineHelper: + +# Add source to this project's executable. +add_library (GlitchyEngineHelper STATIC + "GlitchyEngineHelper.cpp" "GlitchyEngineHelper.h" "vendor/xxHash/xxhash.c" "vendor/xxHash/xxhash.h" "vendor/DirectXTK/Src/DDSTextureLoader.cpp" "DotNetRuntime.h" "DotNetRuntime.cpp" + # Link object files from nethost into library (kinda dirty I think, but avoids linking to nethost.lib when compiling in beef) + $ +) + +target_include_directories(GlitchyEngineHelper PRIVATE + "vendor/DirectXTK/Inc" + ${DOTNET_HOST_DIR} +) + +IF (WIN32) + add_compile_definitions(WINDOWS) +ENDIF() # Use statically linked multithreaded MSVC runtime -set_property(TARGET GlitchyEngineHelper PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreadedDebug") -#$<$:Debug> \ No newline at end of file +set_property(TARGET GlitchyEngineHelper PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") \ No newline at end of file diff --git a/GlitchyEngineHelper/DotNetRuntime.cpp b/GlitchyEngineHelper/DotNetRuntime.cpp new file mode 100644 index 0000000..86cd76e --- /dev/null +++ b/GlitchyEngineHelper/DotNetRuntime.cpp @@ -0,0 +1,251 @@ +#include "DotNetRuntime.h" + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting + +// Standard headers +#include +#include +#include +#include +#include +#include + +// Provided by the AppHost NuGet package and installed as an SDK pack +#include + +// Header files copied from https://github.com/dotnet/core-setup +#include +#include + +#ifdef WINDOWS +#include + +#define STR(s) L ## s +#define CH(c) L ## c +#define DIR_SEPARATOR L'\\' + +#else +#include +#include + +#define STR(s) s +#define CH(c) c +#define DIR_SEPARATOR '/' +#define MAX_PATH PATH_MAX + +#endif + +using string_t = std::basic_string; + +namespace +{ + // Globals to hold hostfxr exports + hostfxr_initialize_for_runtime_config_fn init_fptr; + hostfxr_get_runtime_delegate_fn get_delegate_fptr; + hostfxr_close_fn close_fptr; + + // Forward declarations + bool load_hostfxr(); + load_assembly_and_get_function_pointer_fn get_dotnet_load_assembly(const char_t* assembly); +} + +GE_EXPORT int GE_CALLTYPE DotNet_Init() +{ + if (!load_hostfxr()) + { + assert(false && "Failure: load_hostfxr()"); + return EXIT_FAILURE; + } + + return 0; +} + +GE_EXPORT int GE_CALLTYPE TestRunDotNet(int argc, wchar_t* argv[]) +{ + // Get the current executable's directory + // This sample assumes the managed assembly to load and its runtime configuration file are next to the host + char_t host_path[MAX_PATH]; +#if WINDOWS + auto size = ::GetFullPathNameW(argv[0], sizeof(host_path) / sizeof(char_t), host_path, nullptr); + assert(size != 0); +#else + auto resolved = realpath(argv[0], host_path); + assert(resolved != nullptr); +#endif + + string_t root_path = host_path; + auto pos = root_path.find_last_of(DIR_SEPARATOR); + assert(pos != string_t::npos); + root_path = root_path.substr(0, pos + 1); + + //// + //// STEP 1: Load HostFxr and get exported hosting functions + //// + //if (!load_hostfxr()) + //{ + // assert(false && "Failure: load_hostfxr()"); + // return EXIT_FAILURE; + //} + + // + // STEP 2: Initialize and start the .NET Core runtime + // + const string_t config_path = root_path + STR("DotNetTest.runtimeconfig.json"); + load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer = nullptr; + load_assembly_and_get_function_pointer = get_dotnet_load_assembly(config_path.c_str()); + assert(load_assembly_and_get_function_pointer != nullptr && "Failure: get_dotnet_load_assembly()"); + + // + // STEP 3: Load managed assembly and get function pointer to a managed method + // + const string_t dotnetlib_path = root_path + STR("DotNetTest.dll"); + const char_t* dotnet_type = STR("DotNetTest.Lib, DotNetTest"); + const char_t* dotnet_type_method = STR("Hello"); + // + // Function pointer to managed delegate + component_entry_point_fn hello = nullptr; + int rc = load_assembly_and_get_function_pointer( + dotnetlib_path.c_str(), + dotnet_type, + dotnet_type_method, + nullptr /*delegate_type_name*/, + nullptr, + (void**)&hello); + // + assert(rc == 0 && hello != nullptr && "Failure: load_assembly_and_get_function_pointer()"); + + // + // STEP 4: Run managed code + // + struct lib_args + { + const char_t* message; + int number; + }; + for (int i = 0; i < 3; ++i) + { + // + lib_args args + { + STR("from host!"), + i + }; + + hello(&args, sizeof(args)); + // + } + + // Function pointer to managed delegate with non-default signature + typedef void (CORECLR_DELEGATE_CALLTYPE* custom_entry_point_fn)(lib_args args); + custom_entry_point_fn custom = nullptr; + rc = load_assembly_and_get_function_pointer( + dotnetlib_path.c_str(), + dotnet_type, + STR("CustomEntryPointUnmanaged") /*method_name*/, + UNMANAGEDCALLERSONLY_METHOD, + nullptr, + (void**)&custom); + assert(rc == 0 && custom != nullptr && "Failure: load_assembly_and_get_function_pointer()"); + + lib_args args + { + STR("from host!"), + -1 + }; + custom(args); + + return EXIT_SUCCESS; +} + +/******************************************************************************************** + * Function used to load and activate .NET Core + ********************************************************************************************/ + +namespace +{ + // Forward declarations + void* load_library(const char_t*); + void* get_export(void*, const char*); + +#ifdef WINDOWS + void* load_library(const char_t* path) + { + std::cout << "Loading library: " << path << std::endl; + HMODULE h = ::LoadLibraryW(path); + assert(h != nullptr); + return (void*)h; + } + void* get_export(void* h, const char* name) + { + void* f = ::GetProcAddress((HMODULE)h, name); + assert(f != nullptr); + return f; + } +#else + void* load_library(const char_t* path) + { + void* h = dlopen(path, RTLD_LAZY | RTLD_LOCAL); + assert(h != nullptr); + return h; + } + void* get_export(void* h, const char* name) + { + void* f = dlsym(h, name); + assert(f != nullptr); + return f; + } +#endif + + // + // Using the nethost library, discover the location of hostfxr and get exports + bool load_hostfxr() + { + // Pre-allocate a large buffer for the path to hostfxr + char_t buffer[MAX_PATH]; + size_t buffer_size = sizeof(buffer) / sizeof(char_t); + int rc = get_hostfxr_path(buffer, &buffer_size, nullptr); + if (rc != 0) + return false; + + // Load hostfxr and get desired exports + void* lib = load_library(buffer); + init_fptr = (hostfxr_initialize_for_runtime_config_fn)get_export(lib, "hostfxr_initialize_for_runtime_config"); + get_delegate_fptr = (hostfxr_get_runtime_delegate_fn)get_export(lib, "hostfxr_get_runtime_delegate"); + close_fptr = (hostfxr_close_fn)get_export(lib, "hostfxr_close"); + + return (init_fptr && get_delegate_fptr && close_fptr); + } + // + + // + // Load and initialize .NET Core and get desired function pointer for scenario + load_assembly_and_get_function_pointer_fn get_dotnet_load_assembly(const char_t* config_path) + { + // Load .NET Core + void* load_assembly_and_get_function_pointer = nullptr; + hostfxr_handle cxt = nullptr; + int rc = init_fptr(config_path, nullptr, &cxt); + if (rc != 0 || cxt == nullptr) + { + std::cerr << "Init failed: " << std::hex << std::showbase << rc << std::endl; + close_fptr(cxt); + return nullptr; + } + + // Get the load assembly function pointer + rc = get_delegate_fptr( + cxt, + hdt_load_assembly_and_get_function_pointer, + &load_assembly_and_get_function_pointer); + if (rc != 0 || load_assembly_and_get_function_pointer == nullptr) + std::cerr << "Get delegate failed: " << std::hex << std::showbase << rc << std::endl; + + close_fptr(cxt); + return (load_assembly_and_get_function_pointer_fn)load_assembly_and_get_function_pointer; + } + // +} diff --git a/GlitchyEngineHelper/DotNetRuntime.h b/GlitchyEngineHelper/DotNetRuntime.h new file mode 100644 index 0000000..eda0f37 --- /dev/null +++ b/GlitchyEngineHelper/DotNetRuntime.h @@ -0,0 +1,3 @@ +#pragma once + +#include "GlitchyEngineHelper.h" diff --git a/GlitchyEngineHelper/GlitchyEngineHelper.cpp b/GlitchyEngineHelper/GlitchyEngineHelper.cpp index f59bf79..c89adf6 100644 --- a/GlitchyEngineHelper/GlitchyEngineHelper.cpp +++ b/GlitchyEngineHelper/GlitchyEngineHelper.cpp @@ -2,6 +2,8 @@ // #include "GlitchyEngineHelper.h" +#include "vendor/xxHash/xxhash.h" +#include "vendor/DirectXTK/Inc/DDSTextureLoader.h" using namespace std; diff --git a/GlitchyEngineHelper/GlitchyEngineHelper.h b/GlitchyEngineHelper/GlitchyEngineHelper.h index ca90f7d..1c095f9 100644 --- a/GlitchyEngineHelper/GlitchyEngineHelper.h +++ b/GlitchyEngineHelper/GlitchyEngineHelper.h @@ -5,6 +5,3 @@ #define GE_EXPORT extern "C" __declspec(dllexport) #define GE_CALLTYPE __cdecl - -#include "vendor/xxHash/xxhash.h" -#include "vendor/DirectXTK/Inc/DDSTextureLoader.h" diff --git a/GlitchyEngineHelper/src/DotNetRuntime.bf b/GlitchyEngineHelper/src/DotNetRuntime.bf new file mode 100644 index 0000000..839acf8 --- /dev/null +++ b/GlitchyEngineHelper/src/DotNetRuntime.bf @@ -0,0 +1,13 @@ +using System; +using System.Interop; +namespace GlitchyEngineHelper +{ + static class DotNetRuntime + { + [LinkName("TestRunDotNet"), CallingConvention(.Cdecl)] + public static extern int TestRunDotNet(c_int argc, c_wchar** argv); + + [LinkName("DotNet_Init"), CallingConvention(.Cdecl)] + public static extern int Init(); + } +} \ No newline at end of file diff --git a/GlitchyEngineHelper/vendor/dotnethost/coreclr_delegates.h b/GlitchyEngineHelper/vendor/dotnethost/coreclr_delegates.h new file mode 100644 index 0000000..914ab59 --- /dev/null +++ b/GlitchyEngineHelper/vendor/dotnethost/coreclr_delegates.h @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __CORECLR_DELEGATES_H__ +#define __CORECLR_DELEGATES_H__ + +#include + +#if defined(_WIN32) + #define CORECLR_DELEGATE_CALLTYPE __stdcall + #ifdef _WCHAR_T_DEFINED + typedef wchar_t char_t; + #else + typedef unsigned short char_t; + #endif +#else + #define CORECLR_DELEGATE_CALLTYPE + typedef char char_t; +#endif + +#define UNMANAGEDCALLERSONLY_METHOD ((const char_t*)-1) + +// Signature of delegate returned by coreclr_delegate_type::load_assembly_and_get_function_pointer +typedef int (CORECLR_DELEGATE_CALLTYPE *load_assembly_and_get_function_pointer_fn)( + const char_t *assembly_path /* Fully qualified path to assembly */, + const char_t *type_name /* Assembly qualified type name */, + const char_t *method_name /* Public static method name compatible with delegateType */, + const char_t *delegate_type_name /* Assembly qualified delegate type name or null + or UNMANAGEDCALLERSONLY_METHOD if the method is marked with + the UnmanagedCallersOnlyAttribute. */, + void *reserved /* Extensibility parameter (currently unused and must be 0) */, + /*out*/ void **delegate /* Pointer where to store the function pointer result */); + +// Signature of delegate returned by load_assembly_and_get_function_pointer_fn when delegate_type_name == null (default) +typedef int (CORECLR_DELEGATE_CALLTYPE *component_entry_point_fn)(void *arg, int32_t arg_size_in_bytes); + +typedef int (CORECLR_DELEGATE_CALLTYPE *get_function_pointer_fn)( + const char_t *type_name /* Assembly qualified type name */, + const char_t *method_name /* Public static method name compatible with delegateType */, + const char_t *delegate_type_name /* Assembly qualified delegate type name or null, + or UNMANAGEDCALLERSONLY_METHOD if the method is marked with + the UnmanagedCallersOnlyAttribute. */, + void *load_context /* Extensibility parameter (currently unused and must be 0) */, + void *reserved /* Extensibility parameter (currently unused and must be 0) */, + /*out*/ void **delegate /* Pointer where to store the function pointer result */); + +#endif // __CORECLR_DELEGATES_H__ diff --git a/GlitchyEngineHelper/vendor/dotnethost/hostfxr.h b/GlitchyEngineHelper/vendor/dotnethost/hostfxr.h new file mode 100644 index 0000000..49afae3 --- /dev/null +++ b/GlitchyEngineHelper/vendor/dotnethost/hostfxr.h @@ -0,0 +1,323 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __HOSTFXR_H__ +#define __HOSTFXR_H__ + +#include +#include + +#if defined(_WIN32) + #define HOSTFXR_CALLTYPE __cdecl + #ifdef _WCHAR_T_DEFINED + typedef wchar_t char_t; + #else + typedef unsigned short char_t; + #endif +#else + #define HOSTFXR_CALLTYPE + typedef char char_t; +#endif + +enum hostfxr_delegate_type +{ + hdt_com_activation, + hdt_load_in_memory_assembly, + hdt_winrt_activation, + hdt_com_register, + hdt_com_unregister, + hdt_load_assembly_and_get_function_pointer, + hdt_get_function_pointer, +}; + +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_main_fn)(const int argc, const char_t **argv); +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_main_startupinfo_fn)( + const int argc, + const char_t **argv, + const char_t *host_path, + const char_t *dotnet_root, + const char_t *app_path); +typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_main_bundle_startupinfo_fn)( + const int argc, + const char_t** argv, + const char_t* host_path, + const char_t* dotnet_root, + const char_t* app_path, + int64_t bundle_header_offset); + +typedef void(HOSTFXR_CALLTYPE *hostfxr_error_writer_fn)(const char_t *message); + +// +// Sets a callback which is to be used to write errors to. +// +// Parameters: +// error_writer +// A callback function which will be invoked every time an error is to be reported. +// Or nullptr to unregister previously registered callback and return to the default behavior. +// Return value: +// The previously registered callback (which is now unregistered), or nullptr if no previous callback +// was registered +// +// The error writer is registered per-thread, so the registration is thread-local. On each thread +// only one callback can be registered. Subsequent registrations overwrite the previous ones. +// +// By default no callback is registered in which case the errors are written to stderr. +// +// Each call to the error writer is sort of like writing a single line (the EOL character is omitted). +// Multiple calls to the error writer may occure for one failure. +// +// If the hostfxr invokes functions in hostpolicy as part of its operation, the error writer +// will be propagated to hostpolicy for the duration of the call. This means that errors from +// both hostfxr and hostpolicy will be reporter through the same error writer. +// +typedef hostfxr_error_writer_fn(HOSTFXR_CALLTYPE *hostfxr_set_error_writer_fn)(hostfxr_error_writer_fn error_writer); + +typedef void* hostfxr_handle; +struct hostfxr_initialize_parameters +{ + size_t size; + const char_t *host_path; + const char_t *dotnet_root; +}; + +// +// Initializes the hosting components for a dotnet command line running an application +// +// Parameters: +// argc +// Number of argv arguments +// argv +// Command-line arguments for running an application (as if through the dotnet executable). +// Only command-line arguments which are accepted by runtime installation are supported, SDK/CLI commands are not supported. +// For example 'app.dll app_argument_1 app_argument_2`. +// parameters +// Optional. Additional parameters for initialization +// host_context_handle +// On success, this will be populated with an opaque value representing the initialized host context +// +// Return value: +// Success - Hosting components were successfully initialized +// HostInvalidState - Hosting components are already initialized +// +// This function parses the specified command-line arguments to determine the application to run. It will +// then find the corresponding .runtimeconfig.json and .deps.json with which to resolve frameworks and +// dependencies and prepare everything needed to load the runtime. +// +// This function only supports arguments for running an application. It does not support SDK commands. +// +// This function does not load the runtime. +// +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_initialize_for_dotnet_command_line_fn)( + int argc, + const char_t **argv, + const struct hostfxr_initialize_parameters *parameters, + /*out*/ hostfxr_handle *host_context_handle); + +// +// Initializes the hosting components using a .runtimeconfig.json file +// +// Parameters: +// runtime_config_path +// Path to the .runtimeconfig.json file +// parameters +// Optional. Additional parameters for initialization +// host_context_handle +// On success, this will be populated with an opaque value representing the initialized host context +// +// Return value: +// Success - Hosting components were successfully initialized +// Success_HostAlreadyInitialized - Config is compatible with already initialized hosting components +// Success_DifferentRuntimeProperties - Config has runtime properties that differ from already initialized hosting components +// CoreHostIncompatibleConfig - Config is incompatible with already initialized hosting components +// +// This function will process the .runtimeconfig.json to resolve frameworks and prepare everything needed +// to load the runtime. It will only process the .deps.json from frameworks (not any app/component that +// may be next to the .runtimeconfig.json). +// +// This function does not load the runtime. +// +// If called when the runtime has already been loaded, this function will check if the specified runtime +// config is compatible with the existing runtime. +// +// Both Success_HostAlreadyInitialized and Success_DifferentRuntimeProperties codes are considered successful +// initializations. In the case of Success_DifferentRuntimeProperties, it is left to the consumer to verify that +// the difference in properties is acceptable. +// +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_initialize_for_runtime_config_fn)( + const char_t *runtime_config_path, + const struct hostfxr_initialize_parameters *parameters, + /*out*/ hostfxr_handle *host_context_handle); + +// +// Gets the runtime property value for an initialized host context +// +// Parameters: +// host_context_handle +// Handle to the initialized host context +// name +// Runtime property name +// value +// Out parameter. Pointer to a buffer with the property value. +// +// Return value: +// The error code result. +// +// The buffer pointed to by value is owned by the host context. The lifetime of the buffer is only +// guaranteed until any of the below occur: +// - a 'run' method is called for the host context +// - properties are changed via hostfxr_set_runtime_property_value +// - the host context is closed via 'hostfxr_close' +// +// If host_context_handle is nullptr and an active host context exists, this function will get the +// property value for the active host context. +// +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_property_value_fn)( + const hostfxr_handle host_context_handle, + const char_t *name, + /*out*/ const char_t **value); + +// +// Sets the value of a runtime property for an initialized host context +// +// Parameters: +// host_context_handle +// Handle to the initialized host context +// name +// Runtime property name +// value +// Value to set +// +// Return value: +// The error code result. +// +// Setting properties is only supported for the first host context, before the runtime has been loaded. +// +// If the property already exists in the host context, it will be overwritten. If value is nullptr, the +// property will be removed. +// +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_set_runtime_property_value_fn)( + const hostfxr_handle host_context_handle, + const char_t *name, + const char_t *value); + +// +// Gets all the runtime properties for an initialized host context +// +// Parameters: +// host_context_handle +// Handle to the initialized host context +// count +// [in] Size of the keys and values buffers +// [out] Number of properties returned (size of keys/values buffers used). If the input value is too +// small or keys/values is nullptr, this is populated with the number of available properties +// keys +// Array of pointers to buffers with runtime property keys +// values +// Array of pointers to buffers with runtime property values +// +// Return value: +// The error code result. +// +// The buffers pointed to by keys and values are owned by the host context. The lifetime of the buffers is only +// guaranteed until any of the below occur: +// - a 'run' method is called for the host context +// - properties are changed via hostfxr_set_runtime_property_value +// - the host context is closed via 'hostfxr_close' +// +// If host_context_handle is nullptr and an active host context exists, this function will get the +// properties for the active host context. +// +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_properties_fn)( + const hostfxr_handle host_context_handle, + /*inout*/ size_t * count, + /*out*/ const char_t **keys, + /*out*/ const char_t **values); + +// +// Load CoreCLR and run the application for an initialized host context +// +// Parameters: +// host_context_handle +// Handle to the initialized host context +// +// Return value: +// If the app was successfully run, the exit code of the application. Otherwise, the error code result. +// +// The host_context_handle must have been initialized using hostfxr_initialize_for_dotnet_command_line. +// +// This function will not return until the managed application exits. +// +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_run_app_fn)(const hostfxr_handle host_context_handle); + +// +// Gets a typed delegate from the currently loaded CoreCLR or from a newly created one. +// +// Parameters: +// host_context_handle +// Handle to the initialized host context +// type +// Type of runtime delegate requested +// delegate +// An out parameter that will be assigned the delegate. +// +// Return value: +// The error code result. +// +// If the host_context_handle was initialized using hostfxr_initialize_for_runtime_config, +// then all delegate types are supported. +// If the host_context_handle was initialized using hostfxr_initialize_for_dotnet_command_line, +// then only the following delegate types are currently supported: +// hdt_load_assembly_and_get_function_pointer +// hdt_get_function_pointer +// +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_delegate_fn)( + const hostfxr_handle host_context_handle, + enum hostfxr_delegate_type type, + /*out*/ void **delegate); + +// +// Closes an initialized host context +// +// Parameters: +// host_context_handle +// Handle to the initialized host context +// +// Return value: +// The error code result. +// +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_close_fn)(const hostfxr_handle host_context_handle); + +struct hostfxr_dotnet_environment_sdk_info +{ + size_t size; + const char_t* version; + const char_t* path; +}; + +typedef void(HOSTFXR_CALLTYPE* hostfxr_get_dotnet_environment_info_result_fn)( + const struct hostfxr_dotnet_environment_info* info, + void* result_context); + +struct hostfxr_dotnet_environment_framework_info +{ + size_t size; + const char_t* name; + const char_t* version; + const char_t* path; +}; + +struct hostfxr_dotnet_environment_info +{ + size_t size; + + const char_t* hostfxr_version; + const char_t* hostfxr_commit_hash; + + size_t sdk_count; + const hostfxr_dotnet_environment_sdk_info* sdks; + + size_t framework_count; + const hostfxr_dotnet_environment_framework_info* frameworks; +}; + +#endif //__HOSTFXR_H__ diff --git a/GlitchyEngineHelper/vendor/dotnethost/license.txt b/GlitchyEngineHelper/vendor/dotnethost/license.txt new file mode 100644 index 0000000..984713a --- /dev/null +++ b/GlitchyEngineHelper/vendor/dotnethost/license.txt @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) .NET Foundation and Contributors + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/GlitchyEngineHelper/vendor/dotnethost/nethost.dll b/GlitchyEngineHelper/vendor/dotnethost/nethost.dll new file mode 100644 index 0000000..6f67abd Binary files /dev/null and b/GlitchyEngineHelper/vendor/dotnethost/nethost.dll differ diff --git a/GlitchyEngineHelper/vendor/dotnethost/nethost.h b/GlitchyEngineHelper/vendor/dotnethost/nethost.h new file mode 100644 index 0000000..31adde5 --- /dev/null +++ b/GlitchyEngineHelper/vendor/dotnethost/nethost.h @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __NETHOST_H__ +#define __NETHOST_H__ + +#include + +#ifdef _WIN32 + #ifdef NETHOST_EXPORT + #define NETHOST_API __declspec(dllexport) + #else + // Consuming the nethost as a static library + // Shouldn't export attempt to dllimport. + #ifdef NETHOST_USE_AS_STATIC + #define NETHOST_API + #else + #define NETHOST_API __declspec(dllimport) + #endif + #endif + + #define NETHOST_CALLTYPE __stdcall + #ifdef _WCHAR_T_DEFINED + typedef wchar_t char_t; + #else + typedef unsigned short char_t; + #endif +#else + #ifdef NETHOST_EXPORT + #define NETHOST_API __attribute__((__visibility__("default"))) + #else + #define NETHOST_API + #endif + + #define NETHOST_CALLTYPE + typedef char char_t; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// Parameters for get_hostfxr_path +// +// Fields: +// size +// Size of the struct. This is used for versioning. +// +// assembly_path +// Path to the compenent's assembly. +// If specified, hostfxr is located as if the assembly_path is the apphost +// +// dotnet_root +// Path to directory containing the dotnet executable. +// If specified, hostfxr is located as if an application is started using +// 'dotnet app.dll', which means it will be searched for under the dotnet_root +// path and the assembly_path is ignored. +// +struct get_hostfxr_parameters { + size_t size; + const char_t *assembly_path; + const char_t *dotnet_root; +}; + +// +// Get the path to the hostfxr library +// +// Parameters: +// buffer +// Buffer that will be populated with the hostfxr path, including a null terminator. +// +// buffer_size +// [in] Size of buffer in char_t units. +// [out] Size of buffer used in char_t units. If the input value is too small +// or buffer is nullptr, this is populated with the minimum required size +// in char_t units for a buffer to hold the hostfxr path +// +// get_hostfxr_parameters +// Optional. Parameters that modify the behaviour for locating the hostfxr library. +// If nullptr, hostfxr is located using the enviroment variable or global registration +// +// Return value: +// 0 on success, otherwise failure +// 0x80008098 - buffer is too small (HostApiBufferTooSmall) +// +// Remarks: +// The full search for the hostfxr library is done on every call. To minimize the need +// to call this function multiple times, pass a large buffer (e.g. PATH_MAX). +// +NETHOST_API int NETHOST_CALLTYPE get_hostfxr_path( + char_t * buffer, + size_t * buffer_size, + const struct get_hostfxr_parameters *parameters); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // __NETHOST_H__ diff --git a/GlitchyEngineHelper/vendor/dotnethost/nethost.lib b/GlitchyEngineHelper/vendor/dotnethost/nethost.lib new file mode 100644 index 0000000..5b5a41b Binary files /dev/null and b/GlitchyEngineHelper/vendor/dotnethost/nethost.lib differ