Merged projects with plugins and modules

This commit is contained in:
2024-07-22 01:18:00 +03:00
parent 1fd065f4c2
commit 8ace51c840
59 changed files with 1669 additions and 73 deletions

View File

@@ -0,0 +1,112 @@
using System.Runtime.InteropServices;
using DiscordBotCore;
namespace CppWrapper.LibraryManagement
{
public sealed class ExternLibrary
{
public string LibraryPath { get; init; }
public IntPtr LibraryHandle { get; private set; }
public ExternLibrary(string libraryPath)
{
LibraryPath = libraryPath;
LibraryHandle = IntPtr.Zero;
}
public void InitializeLibrary()
{
if(LibraryHandle != IntPtr.Zero)
{
return;
}
Application.CurrentApplication.Logger.Log($"Loading library {LibraryPath}");
if(!NativeLibrary.TryLoad(LibraryPath, out IntPtr hModule))
{
throw new DllNotFoundException($"Unable to load library {LibraryPath}");
}
Application.CurrentApplication.Logger.Log($"Library {LibraryPath} loaded successfully [{hModule}]");
LibraryHandle = hModule;
}
public void FreeLibrary()
{
if(LibraryHandle == IntPtr.Zero)
{
return;
}
NativeLibrary.Free(LibraryHandle);
LibraryHandle = IntPtr.Zero;
Application.CurrentApplication.Logger.Log($"Library {LibraryPath} freed successfully");
}
private IntPtr GetFunctionPointer(string functionName)
{
if(LibraryHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Library is not loaded");
}
if(!NativeLibrary.TryGetExport(LibraryHandle, functionName, out IntPtr functionPointer))
{
throw new EntryPointNotFoundException($"Unable to find function {functionName}");
}
return functionPointer;
}
public T GetDelegateForFunctionPointer<T>(string methodName) where T : Delegate
{
IntPtr functionPointer = GetFunctionPointer(methodName);
Application.CurrentApplication.Logger.Log($"Function pointer for {methodName} obtained successfully [address: {functionPointer}]");
T result = (T)Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(T));
Application.CurrentApplication.Logger.Log($"Delegate for {methodName} created successfully");
return result;
}
private IntPtr GetFunctionPointerForDelegate<T>(T functionDelegate) where T : Delegate
{
IntPtr functionPointer = Marshal.GetFunctionPointerForDelegate(functionDelegate);
Application.CurrentApplication.Logger.Log($"Function pointer for delegate {functionDelegate.Method.Name} obtained successfully [address: {functionPointer}]");
return functionPointer;
}
/// <summary>
/// Tells the extern setter function to point its function to this C# function instead.
/// This function takes the name of the extern setter function and the C# function to be executed.
/// <para><b>How it works:</b></para>
/// Find the external setter method by its name. It should take one parameter, which is the pointer to the function to be executed.
/// Take the delegate function that should be executed and get its function pointer.
/// Call the external setter with the new function memory address. This should replace the old C++ function with the new C# function.
/// </summary>
/// <param name="setterExternFunctionName">The setter function name</param>
/// <param name="executableFunction">The function that the C++ setter will make its internal function to point to</param>
/// <typeparam name="ExecuteDelegate">A delegate that reflects the executable function structure</typeparam>
/// <typeparam name="SetDelegate">The Setter delegate </typeparam>
/// <returns>A response if it exists as an object</returns>
public object? SetExternFunctionSetterPointerToCustomDelegate<SetDelegate, ExecuteDelegate>(string setterExternFunctionName, ExecuteDelegate executableFunction) where ExecuteDelegate : Delegate where SetDelegate : Delegate
{
SetDelegate setterDelegate = GetDelegateForFunctionPointer<SetDelegate>(setterExternFunctionName);
IntPtr executableFunctionPtr = GetFunctionPointerForDelegate(executableFunction);
var result = setterDelegate.DynamicInvoke(executableFunctionPtr);
Application.CurrentApplication.Logger.Log($"Function {setterExternFunctionName} bound to local action successfully");
return result;
}
}
}