6

私はC#とMonoのフルAOTテクノロジーを使用してiPhone用に開発しています。制限事項ページ(リンクテキスト)によると、従来のMono / .NETとは異なり、iPhoneのコードは、JITコンパイラーによってオンデマンドでコンパイルされるのではなく、事前に静的にコンパイルされます。

ハードウェアで実行すると、次の例外が発生します。

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

制限事項のドキュメントによると、System.Reflection.Emitはサポートされていませんが、Reflection.Emitとは別に、「Type.GetType( "someClass")、メソッドの一覧表示、プロパティの一覧表示、属性の取得を含むReflectionAPI全体」と記載されています。値は問題なく機能します。」

例外の原因となっているコードを含めました...

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

        ...

上記のメソッドは、ハッシュテーブルからプロパティ名を取得し、それを(objとともに)使用してAniValueのインスタンスを作成します。その直後に、foo.Get()が呼び出されてプロパティの値が取得されます。例外は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);
        }
    }
    ...

C#、JIT、AOT、およびReflectionの経験は限られていますが、GetValue()でJITをトリガーする必要がありますか?UnityEngine.Colorは構造体であり、ImageクラスはUnityEngine.MonoBehaviourのサブクラスであるxObjectのサブクラスです。色はImageのプロパティであり、例外が発生したときにコードが値を取得する可能性があります。

興味深いことに、.NET 1.1を使用してコードをコンパイルすると、すべてが正常に実行されます。.NET 2.1を使用してコンパイルした場合にのみ、例外が発生します。

これに対する解決策や回避策があるかどうかはわかりませんが、原因についての洞察に興味があります。

4

1 に答える 1

3

IIRC、リフレクションによるジェネリックに関する警告もあります。具体的な型ではなくインターフェイスを呼び出すと思いますが、特にリフレクションを使用する場合は同じことが当てはまります。

個人的には、iPhone を扱うときにリフレクションを落としているだけです - その方が簡単です。私はまだメタプログラミングを行っていますが、(完全なフレームワークで) 通常のコードを事前に生成しており、それを MonoTouch に引き継いでいます。かなり頑丈そうです。

于 2010-03-11T12:37:53.467 に答える