/*************************************************************************************//*! \file SHDotNetRuntime.h \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Oct 2, 2021 \brief Contains the interface of a wrapper class for interfacing with the .NET 5 Runtime. Copyright (C) 2021 DigiPen Institute of Technology. Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *//**************************************************************************************/ #pragma once // Standard Libraries #include // std::setfill, std::setw #include // std::runtime_error #include // std::string #include // std::ostringstream // External Dependencies #include // HMODULE #include // coreclr_* namespace SHADE { /*************************************************************************************/ /*! class SHDotNetRuntime \brief Class that encapsulates the state of the .NET Core Runtime lifecycle. */ /*************************************************************************************/ class SHDotNetRuntime { public: /*---------------------------------------------------------------------------------*/ /* Constructors/Destructor */ /*---------------------------------------------------------------------------------*/ /***********************************************************************************/ /*! \brief Default constructor that immediately initializes the CoreCLR. \param autoInit If true, loads the CoreCLR by calling Init(). */ /***********************************************************************************/ SHDotNetRuntime(bool autoInit = true); /***********************************************************************************/ /*! \brief Destructor that unloads the CoreCLR if it has not been unloaded yet. */ /***********************************************************************************/ ~SHDotNetRuntime(); // Disallow copy and moving SHDotNetRuntime(const SHDotNetRuntime&) = delete; SHDotNetRuntime(SHDotNetRuntime&&) = delete; /*----------------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*----------------------------------------------------------------------------------*/ /***********************************************************************************/ /*! \brief Loads the CoreCLR and grabs pointers to bootstrapping functions and kickstarts the CoreCLR. \throws std::runtime_error Thrown if there is a failure in loading the CLR and related functions. */ /***********************************************************************************/ void Init(); /***********************************************************************************/ /*! \brief Unloads the CoreCLR. \throws std::runtime_error Thrown if there is a failure in unloading the CLR. */ /***********************************************************************************/ void Exit(); /*----------------------------------------------------------------------------------*/ /* Usage Functions */ /*----------------------------------------------------------------------------------*/ /***********************************************************************************/ /*! \brief Checks if the DotNetRuntime has successfully been initialised. \return True if this DotNetRuntime has been initialised. */ /***********************************************************************************/ inline bool IsLoaded() const noexcept { return initialised; } /***********************************************************************************/ /*! \brief Retrieves a function pointer from the a CLR assembly based on the specified assembly, type and function names. \tparam FunctionType Type of the function pointer that the specified function name will provide. \param assemblyName Name of the CoreCLR assembly that contains the function. \param typeName Name of the CoreCLR type in the assembly that contains the function. Nested types are separated by a period(.). \param functionName Name of the CoreCLR function to get a pointer to. \return Pointer to the function in the assembly that was specified. */ /***********************************************************************************/ template FunctionType GetFunctionPtr(const std::string_view& assemblyName, const std::string_view& typeName, const std::string_view& functionName) const; private: /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ bool initialised = false; // References to CoreCLR key components HMODULE coreClr = nullptr; void* hostHandle = nullptr; unsigned int domainId = 0; // Function Pointers to CoreCLR functions coreclr_initialize_ptr initializeCoreClr = nullptr; coreclr_create_delegate_ptr createManagedDelegate = nullptr; coreclr_shutdown_ptr shutdownCoreClr = nullptr; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ /*---------------------------------------------------------------------------------*/ /***********************************************************************************/ /*! \brief Retrieves a function pointer from the CoreCLR based on the specified function name. \tparam FunctionType Type of the function pointer that the specified function name will provide. \param functionName Name of the CoreCLR function to get a pointer to. \return Pointer to the function in the CoreCLR that was specified. */ /***********************************************************************************/ template FunctionType getCoreClrFunctionPtr(const std::string& functionName); /***********************************************************************************/ /*! \brief Compiles a semicolon separated string of trusted platform assemblies by searching the specified directory. \param directory Path to the directory where the trusted platform assemblies reside. \return Semicolon separated string of trusted platform assemblies. */ /***********************************************************************************/ static std::string buildTpaList(const std::string& directory); /***********************************************************************************/ /*! \brief Takes in a Win32 result code and throws an exception it if there is an error. \param errMsg Error message to display if the resultCode is a failure code. \param resultCode Result code of the function to check. */ /***********************************************************************************/ static void throwIfFailed(const std::string& errMsg, int resultCode); }; } #include "SHDotNetRuntime.hpp"