2010-03-11 14 views
6

Ich entwickle für das iPhone mit C# und Monos Full AOT-Technologie. Laut ihrer Einschränkungen Seite (link text), im Gegensatz zu herkömmlichen Mono/.NET, wird Code auf dem iPhone statisch vor der Zeit kompiliert, anstatt auf Anforderung von einem JIT-Compiler kompiliert werden.Ich bin verwirrt über einige Reflection-Code und auf der Suche nach Einsicht

Wenn auf der Hardware ausgeführt wird, tritt die folgende Ausnahme:

ExecutionEngineException: Attempting to JIT compile method 'System.Reflection.MonoProperty:GetterAdapterFrame<Image, UnityEngine.Color> (System.Reflection.MonoProperty/Getter`2<Image, UnityEngine.Color>,object)' while running with --aot-only. 

System.Reflection.MonoProperty.GetValue (System.Object obj, System.Object[] index) [0x00000] 
Ani+AniValue.Get() 
Ani.CreateAnimations (System.Object obj, System.Collections.Hashtable properties, Single duration, System.Collections.Hashtable options, AniType type) 
Ani.Method (AniType type, System.Object obj, Single duration, System.Collections.Hashtable _properties, System.Collections.Hashtable _options) 
Ani.From (System.Object obj, Single duration, System.Collections.Hashtable _properties) 
xObject+<>c__CompilerGenerated5.MoveNext() 
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) 
xObject:StartAnimation(Animate, GameObject, Object, Object) 
SceneSplash:CreateBackground() 
SceneSplash:OnSetup() 
SceneSplash:OnSceneActivate(Callback) 
GameController:ActivateScene() 
GameController:DeactivateScene() 
GameController:SceneLoaded(Scene, GameObject, SceneBase) 
SceneBase:Start() 

Gemäß dem Dokument Einschränkungen wird System.Reflection.Emit nicht unterstützt, aber sie erklären, dass als Seite von Reflection.Emit „, die Die gesamte Reflection-API, einschließlich Type.GetType ("someClass"), Auflistungsmethoden, Auflistungseigenschaften, Attribute und Werte abrufen funktioniert problemlos. "

ich den Code aufgenommen haben, der die Ausnahme verursacht ...

void CreateAnimations(System.Object obj, Hashtable properties, float duration, 
         Hashtable options, AniType type) 
{ 
    foreach (DictionaryEntry item in properties) 
    { 
     name = (string)item.Key;     // Extract name and value 
     System.Object value = item.Value; 

     AniValue foo = new AniValue(obj, name); // Create value object 

     /* To exception occurs inside Get() */ 
     System.Object current = foo.Get();  // Get current value 

     ... 

Das oben beschriebene Verfahren einen Eigenschaftsnamen von einem Hash-Tabelle packt, und verwendet sie (zusammen mit obj) eine Instanz von AniValue zu erstellen . Kurz danach wird foo.Get() aufgerufen, um den Wert der Eigenschaft abzurufen. Die Ausnahme tritt bei propertyInfo.GetValue (obj, null) auf.

using System.Reflection 

public class AniValue 
{ 
    static BindingFlags bFlags = BindingFlags.Public | BindingFlags.NonPublic 
           | BindingFlags.Instance | BindingFlags.Static; 

    System.Object obj; // Object a field or property is animated on 
    string name;  // Name of the field or property 

    System.Type objType;   // Type object 
    FieldInfo fieldInfo;   // FieldInfo object 
    PropertyInfo propertyInfo; // PropertyInfo object 

    public AniValue(System.Object o, string n) 
    { 
     obj = o; 
     name = n; 
     objType = obj.GetType(); 
     fieldInfo = objType.GetField(n, AniValue.bFlags); 
     propertyInfo = objType.GetProperty(n, AniValue.bFlags); 
     if (fieldInfo == null && propertyInfo == null) 
     { 
      throw new System.MissingMethodException("Property or field '" + n 
                + "' not found on " + obj); 
     } 
    } 

    // Get field or property 
    public System.Object Get() 
    { 
     if (propertyInfo != null) 
     { 
      /* The next line causes the Exception */ 
      return propertyInfo.GetValue(obj, null); 
     } 
     else 
     { 
      return fieldInfo.GetValue(obj); 
     } 
    } 
    ... 

Obwohl ich Erfahrung mit C# begrenzt, JIT, AOT und Reflexion, sollte GetValue() Trigger JIT? UnityEngine.Color ist eine Struktur und die Image-Klasse ist eine Unterklasse von xObject, die eine Unterklasse von UnityEngine.MonoBehaviour ist. Farbe ist eine Eigenschaft von Image. Dies ist der Wert, den der Code beim Auftreten der Ausnahme erhalten kann.

Interessanterweise können Sie den Code mit .NET 1.1 kompilieren, und alles wird gut ausgeführt. Nur wenn Sie mit .NET 2.1 kompilieren, tritt die Ausnahme auf.

Ich weiß nicht, ob es eine Lösung oder eine Lösung gibt, aber ich wäre an jeder Einsicht in die Ursache interessiert.

+0

Dies scheint nicht wirklich S.R.E. zu sein, es könnte ein Fehler in MonoTouch selbst sein, Sie sollten sie oder möglicherweise Unity darüber kontaktieren. – ermau

+0

Ich habe dem Team von Unity einen Fehlerbericht geschickt, nur für den Fall, dass es sich um einen Fehler handelt. –

Antwort

3

IIRC, es gibt auch eine Warnung über Generika über Reflexion. I glaube es ruft Interfaces eher als konkrete Typen, aber das gleiche kann gelten - in insbesondere bei der Verwendung von Reflexion.

Persönlich bin ich nur Reflexion fallen, wenn es um iPhone geht - es ist einfacher. Ich mache immer noch Meta-Programmierung, aber ich generiere regelmäßig Code (auf dem gesamten Framework), den ich dann zu MonoTouch übernehme. Es scheint ziemlich robust zu funktionieren.

+0

Keine Generics werden an dieser Stelle irgendwo im Projektcode verwendet, sonst erwarte ich nicht, dass es unter .NET 1.1 läuft, was auch der Fall ist. Wenn ich den Aufruf von GetValue() manuell bearbeitet habe, läuft der Rest der App gut, auch wenn später Aufrufe von Reflection SetValue() an dieselbe Eigenschaft ausgeführt werden und diese ohne Probleme funktionieren. Das oben verlinkte Limitations-Dokument führt mich zu der Annahme, dass dies funktionieren sollte, da es eindeutig besagt, dass "Auflistungsmethoden, Auflistungseigenschaften, Attribute und Werte abrufen einfach funktionieren". Ich denke, ich werde Ihren Rat nehmen und weg von Reflection. –

+0

@Michael - 'GetterAdapterFrame ' sieht mir generisch –

+1

Es ist sicher. Ich wollte sagen, dass Generika nicht in * meinem * Code verwendet werden. Ich vermute, dass die PropertyInfo.GetValue() -Methode verwendet Generics intern auf dem Mono/.NET 2.1-Framework, und das verursacht die Ausnahme. Vielen Dank! –