Skip to main content

Use Generics

HybridCLR fully supports generic features without any restrictions.

Use generic classes or functions defined in hot update

Just use it directly.

Use generic classes or functions defined in AOT

If some generic class or function has been instantiated in AOT code, it can be used directly in hot update, for example:


// List<float> generic type has been used in AOT
class Foo
{
public void Run()
{
var arr = new List<float>();
}
}

// List<float> can be used in hot update
class HotUpdateGenericDemos
{
public void Run()
{
var arr = new List<float>();
}
}

However, if an AOT generic class or function has not been instantiated in the AOT, certain processing is required. There are two solutions:

  1. Add the corresponding instantiation code in the AOT code.
  2. Supplementary Metadata Technology. This is HybridCLR's patented technology.

Please read AOT Generics for detailed principles of AOT generics.

For method 1, there are several fatal flaws:

  • The instantiation code added to the AOT code needs to be repackaged. Not only is the development period very troublesome, but it is unrealistic to redistribute the main package in a short period of time after it goes online.
  • Generic parameters may be hot update types, which cannot be instantiated in advance in AOT. For example, if you define struct MyVector3 {int x, y, z;} in the hot update code, you cannot instantiate List<MyVector3> in advance in AOT.

Supplementary Metadata Technology completely solves this problem. Roughly speaking, after you supplement the original metadata of the AOT generic class (or generic function), you can instantiate the generic class arbitrarily. Take the above List<MyVector3> as an example, after you add the mscorlib.dll metadata where the List class (not MyVector3) is located, you can use any List<T> generic class in the hot update code up.

get supplementary metadata dll

The stripped AOT dll generated by build process can be used to supplement metadata. The com.code-philosophy.hybridclr plugin will automatically copy them to {project}/HybridCLRData/AssembliesPostIl2CppStrip/{target}.

danger

Stripped AOT dlls of different BuildTargets cannot be reused.

Using the HybridCLR/Generate/AotDlls command can also generate the trimmed AOT dll immediately, it works by exporting a Temp project to get the trimmed AOT dll.

Obtain the supplementary metadata dll you need from the {project}/HybridCLRData/AssembliesPostIl2CppStrip/{target} directory, and add it to the hot update resource management system of the project. The example projects are placed in the StreamingAssets directory for demonstration purposes. Take the List<T> type as an example, it needs to complement mscorlib.dll. Copy {project}/HybridCLRData/AssembliesPostIl2CppStrip/{target}/mscorlib.dll to Assets/StreamingAssets/mscorlib.dll.bytes.

Execute Supplementary Metadata

Use the HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly function in the com.code-philosophy.hybridclr package to supplement metadata for AOT generics. Metadata only needs to be supplemented once, it is recommended before executing any hot update code. LoadDll.cs ends up looking like this.


public class LoadDll : MonoBehaviour
{

void Start()
{
// Add metadata first
LoadMetadataForAOTAAssemblies();
// In the Editor environment, HotUpdate.dll.bytes has been automatically loaded and does not need to be loaded. Repeated loading will cause problems.
#if !UNITY_EDITOR
Assembly hotUpdateAss = Assembly.Load(File.ReadAllBytes($"{Application.streamingAssetsPath}/HotUpdate.dll.bytes"));
#else
// No need to load under Editor, directly find the HotUpdate assembly
Assembly hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "HotUpdate");
#endif

Type type = hotUpdateAss. GetType("Hello");
type. GetMethod("Run"). Invoke(null, null);
}

private static void LoadMetadataForAOTAAssemblies()
{
List<string> aotDllList = new List<string>
{
"mscorlib.dll",
"System.dll",
"System.Core.dll", // required if using Linq
// "Newtonsoft.Json.dll",
// "protobuf-net.dll",
};

foreach (var aotDllName in aotDllList)
{
byte[] dllBytes = File.ReadAllBytes($"{Application.streamingAssetsPath}/{aotDllName}.bytes");
int err = HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, HomologousImageMode.SuperSet);
Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}.ret:{err}");
}
}
}

Now you can freely use AOT generics in hot update code.

Optimize supplementary metadata dll size

The supplementary metadata dll generated by default contains a large amount of data that is not required by the supplementary metadata mechanism. Starting from version v4.0.16, the supplementary metadata dll is supported for elimination and optimization. For detailed documentation, see [AOT Generics](../basic/ aotgeneric).