tzainten
tzainten
CC#
Created by tzainten on 1/4/2023 in #help
❔ Confused about Assembly.Load (Hotloading CSharp Assemblies)
I want to be able to load/unload user made C# libraries during runtime. However, these user libraries rely on one C# FunctionLibrary.dll file I made that will basically hold functions that call Native C++ functions. FunctionLibrary.dll is structured like this:
C#
namespace FunctionLibrary;

public static class Module
{
public static bool Test = false;
}
C#
namespace FunctionLibrary;

public static class Module
{
public static bool Test = false;
}
UserLibrary.dll is structured like this:
C#
using FunctionLibrary;

public class MyLibrary
{
public static void OnStartup()
{
Console.WriteLine(FunctionLibrary.Test);
}
}
C#
using FunctionLibrary;

public class MyLibrary
{
public static void OnStartup()
{
Console.WriteLine(FunctionLibrary.Test);
}
}
FunctionLibrary.dll and UserLibrary.dll are loaded using Assembly.Load, which looks something like this:
C#
public unsafe class Program
{
[UnmanagedCallersOnly]
public static void Main()
{
try
{
Assembly funcLibrary = Assembly.Load(ToMemoryStream(File.OpenRead("FunctionLibrary.dll")));
Type? module = funcLibrary.GetType("FunctionLibrary.Module");
FieldInfo testField = module?.GetField("Test", BindingFlags.Static | BindingFlags.Public);
testField.SetValue(null, true); // Set FunctionLibrary.Module.Test = true

Assembly userLibrary = Assembly.Load(ToMemoryStream(File.OpenRead("UserLibrary.dll")));
Type? userModule = userLibrary.GetType("MyLibrary.MyModule");
MethodInfo entryPoint = userModule?.GetMethod("OnStartup", BindingFlags.Static | BindingFlags.Public);
entryPoint.Invoke(null, null); // Print out the value of FunctionLibrary.Module.Test, expected to == true
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
C#
public unsafe class Program
{
[UnmanagedCallersOnly]
public static void Main()
{
try
{
Assembly funcLibrary = Assembly.Load(ToMemoryStream(File.OpenRead("FunctionLibrary.dll")));
Type? module = funcLibrary.GetType("FunctionLibrary.Module");
FieldInfo testField = module?.GetField("Test", BindingFlags.Static | BindingFlags.Public);
testField.SetValue(null, true); // Set FunctionLibrary.Module.Test = true

Assembly userLibrary = Assembly.Load(ToMemoryStream(File.OpenRead("UserLibrary.dll")));
Type? userModule = userLibrary.GetType("MyLibrary.MyModule");
MethodInfo entryPoint = userModule?.GetMethod("OnStartup", BindingFlags.Static | BindingFlags.Public);
entryPoint.Invoke(null, null); // Print out the value of FunctionLibrary.Module.Test, expected to == true
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
Invoking MyLibrary.OnStartup prints false, not true. I assume I'm just going the wrong way about this, but I'm not really sure how to achieve my goal. I appreciate any help I can get on understanding what I'm doing wrong.
9 replies