2010-03-11 10 views
6

Estoy desarrollando para iPhone usando la tecnología AOT completa de C# y Mono. De acuerdo con su Limitaciones página (link text), a diferencia de Mono/.NET tradicional, el código en el iPhone se compila estáticamente por adelantado en lugar de compilarse bajo demanda por un compilador JIT.Estoy confundido acerca de algún código Reflection, y buscando información

Cuando se ejecuta en el hardware, se produce la siguiente excepción:

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() 

De acuerdo con el documento Limitaciones, System.Reflection.Emit no es compatible, pero afirman que como parte de Reflection.Emit, "la toda la Reflection API, incluyendo Type.GetType ("someClass"), enumerando métodos, enumerando propiedades, obteniendo atributos y valores funciona bien ".

he incluido el código que está causando la excepción ...

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 

     ... 

El método anterior agarra un nombre de propiedad de una tabla hash, y lo utiliza (junto con obj) para crear una instancia de AniValue . Justo después, se llama a foo.Get() para recuperar el valor de la propiedad. La excepción ocurre en propertyInfo.GetValue (obj, null).

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); 
     } 
    } 
    ... 

Aunque he experiencia con C#, JIT, AOT y la reflexión, en caso de GetValue() JIT gatillo limitado? UnityEngine.Color es una estructura, y la clase Image es como una subclase de xObject, que es una subclase de UnityEngine.MonoBehaviour. El color es una propiedad de Image, y eso es lo que el código podría obtener el valor de cuando ocurre la excepción.

Curiosamente, puede compilar el código usando .NET 1.1, y todo funciona bien. Solo cuando compila con .NET 2.1 ocurre la excepción.

No sé si hay una solución o solución a esto, pero me interesaría saber cuál es la causa.

+0

Esto realmente no parece ser S.R.E., puede ser un error en MonoTouch, debe ponerse en contacto con ellos o posiblemente con Unity al respecto. – ermau

+0

Envié un informe de error al equipo de Unity, por si acaso es un error. –

Respuesta

3

IIRC, también hay una advertencia sobre los genéricos a través de la reflexión. I crea llama interfaces en lugar de tipos de hormigón, pero lo mismo puede aplicarse - en particular al usar la reflexión.

Personalmente, me estoy quedando sin reflexión cuando se trata de iPhone - es más fácil. Todavía estoy haciendo metaprogramación, pero estoy pregenerando código regular (en el marco completo) que luego asumo a MonoTouch. Parece que funciona bastante fuerte.

+0

No se utilizan genéricos en este momento en ningún lugar del código del proyecto; de lo contrario, no espero que se ejecute en .NET 1.1, que sí lo es. Además, cuando resolví manualmente la llamada GetValue() problemática, el resto de la aplicación funciona bien, aunque hay llamadas Reflection SetValue() posteriores a la misma propiedad y funcionan sin problemas. El documento de limitaciones vinculado anteriormente me hace creer que esto debería funcionar, ya que indica claramente que "enumerar métodos, enumerar propiedades, recuperar atributos y valores funciona bien". Creo que seguiré su consejo y me alejaré de Reflection. –

+0

@Michael - 'GetterAdapterFrame ' me parece genérico –

+1

Seguro que sí. Quise decir que los genéricos no se usan en el código * my *. Supongo que el PropertyInfo.El método GetValue() usa genéricos internamente en el Framework Mono/.NET 2.1, y eso está causando la excepción. ¡Gracias! –

Cuestiones relacionadas