【问题标题】:Invoke generic method via reflection in C# IL2CPP on iOS在 iOS 上通过 C# IL2CPP 中的反射调用泛型方法
【发布时间】:2019-05-17 09:35:05
【问题描述】:

这个问题专门针对 Unity3d IL2CPP 和 iOS。

使用反射调用泛型方法

class SourceValue<T> { public T value; }
class TargetValue<T> { public T value; }

static TargetValue<T> GenericMethod<T> (SourceValue<T> source) {
    return new TargetValue<T> { value = source.value };
}

void Main () {
    Type genericType = typeof(SourceValue<float>);
    Type typeArg = genericType.GenericTypeArguments[0];
    MethodInfo mi = GetType ().GetMethod ("GenericMethod", Flags | BindingFlags.Static);
    MethodInfo gmi = mi.MakeGenericMethod (typeArg);
    object src = new SourceValue<float> { value = 0.5f };
    object trg = gmi.Invoke (this, new object[] { src });
}

在 Mac 上的 Unity 编辑器中运行时,这可以正常工作。在 iOS 上调用失败并出现错误:

ExecutionEngineException: Attempting to call method 'GenericMethod<System.Single>' for which no ahead of time (AOT) code was generated.
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <00000000000000000000000000000000>:0  

仅仅是AOT系统不能调用泛型方法还是我遗漏了什么?

【问题讨论】:

    标签: c# ios unity3d reflection il2cpp


    【解决方案1】:

    是的,因为 IL2CPP 是一个提前 (AOT) 编译器,它只适用于编译时存在的代码。这里没有代码在“真正的”C# 源代码中使用GenericMethod&lt;float&gt;,因此 IL2CPP 不知道生成相应的代码以使该实现工作。

    这里真正的限制是泛型参数类型是float,这是一个值类型。在这种情况下,您可以使用string(引用类型)而不会出现任何问题。 IL2CPP 共享所有具有作为引用类型的泛型参数的泛型类型的实现(例如stringobject 等)。这是可能的,因为 C# 中的所有引用类型的大小都相同(确切地说是IntrPtr.Size)。

    所以这里的限制实际上是双重的:

    1. IL2CPP 只能生成编译时知道的代码
    2. 此限制仅适用于类型参数为值类型时的泛型类型。

    请注意,理论上 IL2CPP 也可以与值类型泛型参数共享泛型类型的实现,尽管这尚未实现。

    【讨论】:

    • 非常感谢!这回答了我所有的问题,并为我需要解决的现实生活中的问题提供了一个很好的解决方案。我认为我可以将最常见的值类型作为非泛型的特殊情况处理,并且其余代码可以使用任何非值类型进行扩展。这太棒了!从另一个角度来看, GenericMethod> 会起作用吗?其中 Holder 是一个通用的非值类型。
    • 如果在非反射 C# 代码中使用 Holder 将起作用,以便 IL2CPP 可以注意到它并为其生成代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多