BepInEx / Il2CppInterop

A tool interoperate between CoreCLR and Il2Cpp at runtime
GNU Lesser General Public License v3.0
197 stars 64 forks source link

RegisterTypeInIl2Cpp: Support injecting generic types #22

Open Albeoris opened 2 years ago

Albeoris commented 2 years ago

Describe your proposal

Generic types such as Dictionary, List and HashSet are very helpful in mod development.

Now we have to use Dictionary<Object, Object>, as it is most often found in every game. But it also does not support all the necessary methods, for example TryGetValue is often not available.

I'd like to get support for Generic types. It is not yet clear how they differ conceptually from any other types, since at the IL2CPP level we will get a specific type, like Dictionary_String_String.

Error:

ClassInjector.RegisterTypeInIl2Cpp<Dictionary<String, String>>();
System.Exception: Failed to register required types. ---> System.ArgumentException: Type Il2CppSystem.Collections.Generic.Dictionary`2[System.String,System.String] is generic and can't be used in il2cpp
  at UnhollowerRuntimeLib.ClassInjector.RegisterTypeInIl2Cpp (System.Type type, UnhollowerRuntimeLib.RegisterTypeOptions options) [0x00071] in <38fa7eb6c12441c8a8621750ed4c48b6>:0 
  at UnhollowerRuntimeLib.ClassInjector.RegisterTypeInIl2Cpp (System.Type type) [0x00000] in <38fa7eb6c12441c8a8621750ed4c48b6>:0 
  at UnhollowerRuntimeLib.ClassInjector.RegisterTypeInIl2Cpp[T] () [0x00000] in <38fa7eb6c12441c8a8621750ed4c48b6>:0 

Proposed solution

Add the ability to register a specific Generic type and all its methods.

If such a type is already registered, register the methods that are missing because they were not used at the time of compilation.

Alternatives

In the case of Dictionary, List and HashSet, we can continue to use Dictionary<Object, Object> under hood, but provide a clever wrapper like

IDictionary<String, String> dic = GenericFactory.GetDictionary<String,String>();

for Reference types.

Related: BepInEx/BepInEx#334

ghorsington commented 2 years ago

Greetings!

Thank you for the proposal. This, however, is related more to Il2CppUnhollower which is the library for Il2Cpp<->Managed interop. I'll move the issue to our Il2CppUnhollower repo instead.

HookedBehemoth commented 1 month ago

If this is still a requested feature, I could look into it, as I've worked on the Class-Injector before for generics and interfaces. I'm a little bit confused by this issue thread though. How would you work with the injected type? Do you want to pass it to il2cpp code or use it yourself somewhere? The example you provided is a standard library type and is not inheriting from Il2CppObjectBase.