Skip to main content
Version: Next

Quick Start

Almost identical to the community version's Quick Start, this document only introduces the differences.

Installation

  • Extract hybridclr_unity and place it in the project Packages directory, rename it to com.code-philosophy.hybridclr
  • Extract the corresponding il2cpp_plus-{version}.zip according to your Unity version
  • Extract hybridclr.zip
  • Place the hybridclr directory from the extracted hybridclr.zip into the libil2cpp directory from the extracted il2cpp-{version}.zip
  • Open HybridCLR/Installer, enable the Copy libil2cpp from local option, select the libil2cpp directory you just extracted, and perform the installation

installer

Usage in Code

Call RuntimeApi.TryUnloadAssembly or RuntimeApi.ForceUnloadAssembly to unload assemblies, use Assembly.Load to reload assemblies. You must successfully unload an assembly before you can load it again.

Currently there are two unloading workflows:

  • TryUnloadAssembly
  • ForceUnloadAssembly

TryUnloadAssembly

Attempts to unload. If there are references to objects in the unloaded assembly in the AppDomain, it maintains the current state and returns failure; otherwise returns success.

Example code as follows:


// First load
Assembly ass = Assembly.Load(yyy);

// Execute some code
Type mainType = ass.GetType("Entry");
mainType.GetMethod("Main").Invoke(null, null);

// First unload
// printObjectReferenceLink=true will maintain object reference relationships, causing unloading to be time-consuming.
// First try unloading with printObjectReferenceLink=false, if it fails set printObjectReferenceLink=true,
// try unloading again and print illegal reference logs
var report = RuntimeApi.TryUnloadAssembly(ass, false);
if (!report.success)
{
report = RuntimeApi.TryUnloadAssembly(ass, true);
foreach (string log in report.invalidObjectReferenceLinkLogs)
{
Debug.LogError(log);
}
throw new Exception("unload fail");
}

// Second load
Assembly newAss = Assembly.Load(yyy);

// Execute some code
mainType = ass.GetType("Entry");
mainType.GetMethod("Main").Invoke(null, null);

// Second unload
report = RuntimeApi.TryUnloadAssembly(ass, false);
if (!report.success)
{
report = RuntimeApi.TryUnloadAssembly(ass, true);
foreach (string log in report.invalidObjectReferenceLinkLogs)
{
Debug.LogError(log);
}
throw new Exception("unload fail");
}

ForceUnloadAssembly

Force unload, even if there are references to objects in the unloaded assembly in the AppDomain. Returns true if there are no problems, returns false if illegal references are detected during unloading. If it returns false, it may crash after running for a while. Use this operation with caution, it's recommended to communicate in detail with official technical support.


// First load
Assembly ass = Assembly.Load(yyy);

// Execute some code
Type mainType = ass.GetType("Entry");
mainType.GetMethod("Main").Invoke(null, null);

// First unload
// ignoreObjectReferenceValidation parameter as true means not checking illegal object references during unloading, which can shorten unloading time. But it's recommended to set to false both during development and production release
// printObjectReferenceLink parameter as true means when unloading fails, detailed illegal object reference chain logs will be printed to help developers locate where illegal references are maintained. It's recommended to be true only during development, change to false after production release
var report = RuntimeApi.ForceUnloadAssembly(ass, false, true);
if (!report.success)
{
foreach (string log in report.invalidObjectReferenceLinkLogs)
{
Debug.LogError(log);
}
throw new Exception("unload fail");
}

// Second load
Assembly newAss = Assembly.Load(yyy);

// Execute some code
mainType = ass.GetType("Entry");
mainType.GetMethod("Main").Invoke(null, null);

// Second unload
report = RuntimeApi.ForceUnloadAssembly(ass, false, true);
if (!report.success)
{
foreach (string log in report.invalidObjectReferenceLinkLogs)
{
Debug.LogError(log);
}
throw new Exception("unload fail");
}

Precautions

  • Async or coroutines can easily implicitly maintain references to unloaded assembly code in other threads. Be sure to clear all async or coroutine functions before unloading
  • UI OnClick or various callback events can easily cause maintaining references to unloaded assemblies, must be cleaned thoroughly
  • Events registered globally or other callbacks can easily accidentally maintain references to unloaded assemblies, must be cleaned thoroughly
  • According to the illegal reference logs printed during unloading, clean up illegal references in the code