116 lines
5.0 KiB
C++
116 lines
5.0 KiB
C++
#pragma once
|
|
#include <spdlog/spdlog.h>
|
|
#include <spdlog/sinks/basic_file_sink.h>
|
|
|
|
// Forward declarations Mono
|
|
struct MonoDomain;
|
|
struct MonoAssembly;
|
|
struct MonoImage;
|
|
struct MonoClass;
|
|
struct MonoMethod;
|
|
struct MonoMethodSignature;
|
|
|
|
// Typedefs pour les exports Mono
|
|
using mono_assembly_foreach_t = void(*)(void(*)(MonoAssembly*, void*), void*);
|
|
using mono_assembly_get_name_t = const void* (*)(MonoAssembly*);
|
|
using mono_assembly_name_get_name_t = const char* (*)(const void*);
|
|
using mono_class_get_methods_t = MonoMethod * (*)(MonoClass*, void**);
|
|
using mono_method_get_name_t = const char* (*)(MonoMethod*);
|
|
using mono_method_signature_t = MonoMethodSignature * (*)(MonoMethod*);
|
|
using mono_signature_get_param_count_t = uint32_t(*)(MonoMethodSignature*);
|
|
|
|
class MonoLoader {
|
|
public:
|
|
MonoLoader() = default;
|
|
~MonoLoader() = default;
|
|
|
|
/**
|
|
* @brief Callback used during Mono assembly enumeration.
|
|
*
|
|
* This function is passed to `mono_assembly_foreach` and checks each loaded assembly
|
|
* to find the one matching a specific name (provided via userData).
|
|
* Can be used to initialize pointers to target assemblies.
|
|
*
|
|
* @param assembly Pointer to the current assembly.
|
|
* @param userData User data passed to `mono_assembly_foreach`, typically a structure
|
|
* containing the target name and a location to store the result.
|
|
*/
|
|
bool Initialize(std::shared_ptr<spdlog::logger> log = nullptr, const char* monoName = "mono-2.0-bdwgc.dll");
|
|
MonoDomain* GetDomain() const { return g_monoDomain; }
|
|
|
|
/**
|
|
* @brief Finds a Mono assembly by its name.
|
|
*
|
|
* This function iterates over all loaded assemblies in the Mono domain and
|
|
* returns a pointer to the assembly matching the given name.
|
|
*
|
|
* @param name Name of the assembly to search for.
|
|
* @return MonoAssembly* Pointer to the found assembly, or nullptr if not found.
|
|
*/
|
|
MonoAssembly* FindAssembly(const std::string& name);
|
|
|
|
/**
|
|
* @brief Finds a class in a loaded assembly by namespace and name.
|
|
* @param assemblyName Name of the assembly (ex: "UnityEngine.CoreModule").
|
|
* @param namespaceName Namespace of the class (ex: "UnityEngine").
|
|
* @param className Name of the class (ex: "Screen").
|
|
* @return Pointer to the MonoClass, or nullptr if not found.
|
|
*/
|
|
MonoClass* FindClass(const std::string& assemblyName, const std::string& namespaceName, const std::string& className);
|
|
|
|
/**
|
|
* @brief Finds a method in a MonoClass and compiles it.
|
|
* @param monoClass The MonoClass to search in.
|
|
* @param methodName The method name (ex: "get_width").
|
|
* @param paramCount Number of parameters.
|
|
* @return Compiled method address (uint8_t*), or nullptr if not found.
|
|
*/
|
|
uint8_t* GetCompiledMethod(MonoClass* monoClass, const std::string& methodName, int paramCount);
|
|
|
|
void DumpMethods(MonoClass* monoClass, std::shared_ptr<spdlog::logger> log = nullptr);
|
|
|
|
// Exports
|
|
mono_assembly_foreach_t mono_assembly_foreach = nullptr;
|
|
mono_assembly_get_name_t mono_assembly_get_name = nullptr;
|
|
mono_assembly_name_get_name_t mono_assembly_name_get_name = nullptr;
|
|
MonoDomain* (*g_mono_get_root_domain)() = nullptr;
|
|
void (*g_mono_thread_attach)(MonoDomain*) = nullptr;
|
|
MonoAssembly* (*g_mono_domain_assembly_open)(MonoDomain*, const char*) = nullptr;
|
|
MonoImage* (*g_mono_assembly_get_image)(MonoAssembly*) = nullptr;
|
|
MonoClass* (*g_mono_class_from_name)(MonoImage*, const char*, const char*) = nullptr;
|
|
MonoMethod* (*g_mono_class_get_method_from_name)(MonoClass*, const char*, int) = nullptr;
|
|
void* (*g_mono_compile_method)(MonoMethod*) = nullptr;
|
|
mono_class_get_methods_t mono_class_get_methods = nullptr;
|
|
mono_method_get_name_t mono_method_get_name = nullptr;
|
|
mono_method_signature_t mono_method_signature = nullptr;
|
|
mono_signature_get_param_count_t mono_signature_get_param_count = nullptr;
|
|
|
|
|
|
private:
|
|
MonoDomain* g_monoDomain = nullptr;
|
|
std::shared_ptr<spdlog::logger> logger;
|
|
|
|
/**
|
|
* @brief Waits for the Mono module to be loaded in the process and returns its handle.
|
|
*
|
|
* This function loops every 200 ms until the "mono-2.0-bdwgc.dll" module
|
|
* is present in the current process. Useful to ensure that Mono is initialized
|
|
* before resolving its exports.
|
|
*
|
|
* @return HMODULE Handle of the Mono module, or nullptr if not found (practically never).
|
|
*/
|
|
HMODULE WaitForMono(const char* monoName);
|
|
|
|
/**
|
|
* @brief Callback used during Mono assembly enumeration.
|
|
*
|
|
* This function is passed to `mono_assembly_foreach` and checks each loaded assembly
|
|
* to find the one matching a specific name (provided via userData).
|
|
* Can be used to initialize pointers to target assemblies.
|
|
*
|
|
* @param assembly Pointer to the current assembly.
|
|
* @param userData User data passed to `mono_assembly_foreach`, typically a structure
|
|
* containing the target name and a location to store the result.
|
|
*/
|
|
static void FindAssemblyCallback(MonoAssembly* assembly, void* userData);
|
|
}; |