Jejak stack terkelola dengan IL2CPP
Dikelola kode pengupasan

Batasan Scripting

Unity menyediakan API scripting umum dan pengalaman di semua platform yang mendukungnya. Namun, beberapa platform memiliki batasan yang melekat. Untuk membantu Anda memahami pembatasan ini, tabel berikut menjelaskan pembatasan yang berlaku untuk setiap platform dan scripting backendKerangka kerja yang skrip di Unity. Unity mendukung tiga backend scripting yang berbeda tergantung pada platform target: Mono, .NET dan IL2CPP. Platform Windows Universal, namun hanya mendukung dua: .NET dan IL2CPP. More info
Lihat di Glossary
:

.NET 4.x setara scripting runtime

Platform (scripting backend) Ahead-of-time compile No threads .NET Core class libraries subset
Android (IL2CPP)
Android (Mono)
iOS (IL2CPP)
Standalone (IL2CPP)
Standalone (Mono)
Universal Windows PlatformFitur IAP yang mendukung simulator Pembelian Aplikasi Microsoft, yang memungkinkan Anda untuk menguji aliran pembelian IAP pada perangkat sebelum menerbitkan aplikasi Anda. More info
Lihat di Glossary
(IL2CPP)
Platform Windows Universal (.NET)
WebGLLogin API yang membuat grafis 2D dan 3D di browser web. Opsi build Unity WebGL memungkinkan Unity untuk mempublikasikan konten sebagai program JavaScript yang menggunakan teknologi HTML5 dan WebGL rendering API untuk menjalankan konten Unity di browser web. More info
Lihat di Glossary
(IL2CPP)

Ahead-of-time compile

Beberapa platform tidak memungkinkan generasi kode runtime. Oleh karena itu, setiap kode terkelola yang tergantung pada kompilasi tepat waktu (JIT) pada perangkat target akan gagal. Sebagai gantinya, Anda harus mengkompilasi semua kode yang dikelola terlebih dahulu (AOT). Seringkali, perbedaan ini tidak masalah, tetapi dalam beberapa kasus tertentu, platform AOT memerlukan pertimbangan tambahan.

Sistem.Reflection. Login

Platform AOT tidak dapat mengimplementasikan metode di ruang nama System.Reflection.Emit. Sisa System.Reflection diterima, selama kompiler dapat mengganggu bahwa kode yang digunakan melalui refleksi perlu ada di runtime.

Serial

Platform AOT mungkin menghadapi masalah dengan serialisasi dan deserialisasi karena penggunaan refleksi. Jika jenis atau metode hanya digunakan melalui refleksi sebagai bagian dari serialisasi atau deserialisasi, kompilator AOT tidak dapat mendeteksi bahwa perlu menghasilkan kebutuhan kode untuk jenis atau metode.

Metode virtual generik

Jika Anda menggunakan metode generik, kompiler harus melakukan beberapa pekerjaan tambahan untuk memperluas kode tertulis Anda ke kode yang dieksekusi pada perangkat. Misalnya, Anda perlu kode yang berbeda untuk List dengan int atau double. Jika Anda menggunakan metode virtual, di mana perilaku ditentukan pada runtime daripada waktu kompilasi, kompiler dapat dengan mudah memerlukan generasi kode runtime di tempat-tempat di mana tidak sepenuhnya jelas dari kode sumber.

Contoh kode berikut bekerja persis seperti yang diharapkan pada platform JIT (contohnya mencetak “nilai pengukuran: Nol” ke konsol sekali):

using UnityEngine;
using System;

public class AOTProblemExample : MonoBehaviour, IReceiver
{
    public enum AnyEnum 
    {
        Zero,
        One,
    }

    void Start() 
    {
        // Subtle trigger: The type of manager *must* be
        // IManager, not Manager, to trigger the AOT problem.
        IManager manager = new Manager();
        manager.SendMessage(this, AnyEnum.Zero);
    }

    public void OnMessage<T>(T value) 
    {
        Debug.LogFormat("Message value: {0}", value);
    }
}

public class Manager : IManager 
{
    public void SendMessage<T>(IReceiver target, T value) {
        target.OnMessage(value);
    }
}

public interface IReceiver
{
    void OnMessage<T>(T value);
}

public interface IManager 
{
    void SendMessage<T>(IReceiver target, T value);
}

Namun, ketika Anda mengeksekusi kode ini pada platform AOT dengan backend scripting IL2CPPBack-end scripting bersatu yang dapat Anda gunakan sebagai alternatif untuk Mono ketika proyek bangunan untuk beberapa platform. More info
Lihat di Glossary
, pengecualian ini terjadi:

ExecutionEngineException: Attempting to call method 'AOTProblemExample::OnMessage<AOTProblemExample+AnyEnum>' for which no ahead of time (AOT) code was generated.
  at Manager.SendMessage[T] (IReceiver target, .T value) [0x00000] in <filename unknown>:0 
  at AOTProblemExample.Start () [0x00000] in <filename unknown>:0 

Demikian juga, backend skrip Mono memberikan pengecualian serupa ini:

  ExecutionEngineException: Attempting to JIT compile method 'Manager:SendMessage<AOTProblemExample/AnyEnum> (IReceiver,AOTProblemExample/AnyEnum)' while running with --aot-only.
  at AOTProblemExample.Start () [0x00000] in <filename unknown>:0 

compiler AOT tidak mengenali bahwa harus menghasilkan kode untuk metode generik OnMessage dengan T AnyEnum, sehingga terus, melewatkan metode ini. Ketika metode itu disebut, dan runtime tidak dapat menemukan kode yang tepat untuk dieksekusi, itu mengembalikan pesan kesalahan ini.

Untuk bekerja di sekitar masalah AOT seperti ini, Anda dapat memaksa kompiler untuk menghasilkan kode yang tepat. Untuk melakukan ini, tambahkan metode contoh berikut ke kelas AOTProblemExample:

public void UsedOnlyForAOTCodeGeneration() 
{
    // IL2CPP needs only this line.
    OnMessage(AnyEnum.Zero);

    // Mono also needs this line. Note that we are
    // calling directly on the Manager, not the IManager interface.
    new Manager().SendMessage(null, AnyEnum.Zero);

    // Include an exception so we can be sure to know if this method is ever called.
    throw new InvalidOperationException("This method is used for AOT code generation only. Do not call it at runtime.");
}

Ketika kompilator menemukan panggilan eksplisit ke OnMessage dengan T AnyEnum, itu menghasilkan kode yang tepat untuk runtime untuk dijalankan. Metode UsedOnlyForAOTCodeGeneration tidak perlu disebut; itu hanya perlu ada untuk kompiler untuk mengenalinya.

Memanggil metode yang dikelola dari kode asli

Metode yang terkelola yang perlu dihadirkan ke pointer fungsi C sehingga mereka dapat dipanggil dari kode asli memiliki beberapa pembatasan pada platform AOT:

  • Metode yang dikelola harus menjadi metode statis
  • Metode yang dikelola harus memiliki atribut [MonoPInvokeCallback] attribute

Tidak ada benang

Beberapa platform tidak mendukung penggunaan benang, sehingga setiap kode yang berhasil yang menggunakan namespace System.Threading gagal pada runtime. Juga, beberapa bagian perpustakaan kelas .NET tidak bergantung pada benang. Contoh yang sering digunakan adalah kelas System.Timers.Timer, yang tergantung pada dukungan untuk benang.

Kecuali filter

IL2CPP tidak mendukung filter pengecualian C#. Anda harus memodifikasi kode yang tergantung pada filter pengecualian ke blok catch yang tepat.

TypedReference

IL2CPP tidak mendukung tipe System.TypedReference atau kata kunci __makeref C#.

MarshalAs dan atribut FieldOffset

IL2CPP tidak mendukung refleksi atribut MarhsalAs dan FieldOffset pada runtime. Ini tidak mendukung atribut ini pada waktu kompilasi. Anda harus menggunakan ini untuk WordPress.org yang tepat.

Kata kunci dinamis

IL2CPP tidak mendukung kata kunci C# dynamic. Kata kunci ini membutuhkan kompilasi JIT, yang tidak mungkin dengan IL2CPP.

Login Login

IL2CPP tidak mendukung metode API Marshal.Prelink atau Marshal.PrelinkAll.

Jejak stack terkelola dengan IL2CPP
Dikelola kode pengupasan