2010-03-11 23 views
6

Tôi đang phát triển cho iPhone sử dụng công nghệ Full AOT của C# và Mono. Theo giới hạn Hạn chế của chúng tôi (link text), không giống như Mono/.NET truyền thống, mã trên iPhone được biên dịch tĩnh trước thời hạn thay vì được biên dịch theo yêu cầu của trình biên dịch JIT.Tôi đang bối rối về một số mã Phản chiếu và tìm kiếm thông tin chi tiết

Khi chạy trên phần cứng, ngoại trừ sau đây xảy ra:

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

Theo tài liệu hạn chế, System.Reflection.Emit không được hỗ trợ, nhưng họ nói rằng như bên từ Reflection.Emit, "các toàn bộ API phản chiếu, bao gồm Type.GetType ("someClass"), các phương thức liệt kê, các thuộc tính danh sách, các thuộc tính và giá trị tìm nạp hoạt động tốt. "

Tôi đã bao gồm mã đó gây ra các ngoại lệ ...

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 

     ... 

Các phương pháp trên lấy một tên tài sản từ một Hashtable, và sử dụng nó (cùng với obj) để tạo ra một thể hiện của AniValue . Ngay sau đó, foo.Get() được gọi để lấy giá trị của thuộc tính. Ngoại lệ xảy ra trên 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); 
     } 
    } 
    ... 

Mặc dù tôi đã trải nghiệm với C#, JIT, AOT, và Reflection, nên GetValue() kích hoạt JIT giới hạn? UnityEngine.Color là một cấu trúc, và lớp Image là lớp con của xObject, là một lớp con của UnityEngine.MonoBehaviour. Màu là một thuộc tính của hình ảnh, và đó là những gì mã có thể nhận được giá trị khi ngoại lệ xảy ra.

Điều thú vị là bạn có thể biên dịch mã bằng .NET 1.1 và mọi thứ đều hoạt động tốt. Chỉ khi bạn biên dịch bằng .NET 2.1 thì ngoại lệ mới xảy ra.

Tôi không biết nếu có một giải pháp hay làm việc xung quanh điều này, nhưng tôi sẽ quan tâm đến bất kỳ cái nhìn sâu sắc nào về nguyên nhân.

+0

Điều này thực sự không phải là S.R.E., nó có thể là một lỗi trong chính MonoTouch, bạn nên liên hệ với họ hoặc có thể là Unity về nó. – ermau

+0

Tôi đã gửi báo cáo lỗi cho nhóm Unity, trong trường hợp đó là lỗi. –

Trả lời

3

IIRC, cũng có một cảnh báo về generics thông qua phản ánh. Tôi tin rằng nó gọi ra các giao diện thay vì các loại cụ thể, nhưng điều tương tự có thể áp dụng - trong cụ thể khi sử dụng phản chiếu.

Cá nhân, tôi chỉ giảm phản xạ khi giao dịch với iPhone - việc này dễ dàng hơn. Tôi vẫn đang làm siêu lập trình, nhưng tôi đang tạo trước mã thông thường (trên toàn bộ khung công tác) mà sau đó tôi chuyển sang MonoTouch. Dường như nó hoạt động khá mạnh mẽ.

+0

Không có generics nào đang được sử dụng tại thời điểm này ở bất kỳ đâu trong mã dự án, nếu không tôi không mong đợi nó sẽ chạy dưới .NET 1.1, có nghĩa là không. Hơn nữa, khi tôi làm việc theo cách thủ công xung quanh vấn đề GetValue() gọi, phần còn lại của ứng dụng chạy tốt, mặc dù có sau này Reflection SetValue() gọi đến cùng một tài sản và những công việc mà không có vấn đề. Tài liệu Giới hạn được liên kết ở trên dẫn tôi tin rằng điều này sẽ hoạt động, vì nó nêu rõ, "phương pháp liệt kê, thuộc tính danh sách, thuộc tính tìm nạp và giá trị hoạt động tốt". Tôi nghĩ rằng tôi sẽ đưa ra lời khuyên của bạn và di chuyển ra khỏi Reflection. –

+0

@Michael - 'GetterAdapterFrame ' trông giống với tôi –

+1

Nó chắc chắn không. Tôi có nghĩa là để nói generics không được sử dụng trong * mã * của tôi. Tôi đoán rằng PropertyInfo.Phương thức GetValue() sử dụng generics trong nội bộ trên Mono/.NET 2.1 Framework, và điều đó gây ra ngoại lệ. Cảm ơn! –

Các vấn đề liên quan