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 extractedil2cpp-{version}.zip
- Open
HybridCLR/Installer
, enable theCopy libil2cpp from local
option, select the libil2cpp directory you just extracted, and perform the installation
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