Version: 2023.1
언어: 한국어
IL2CPP로 관리되는 스택 추적
관리되는 코드 스트리핑

스크립팅 제약

Unity는 지원하는 모든 플랫폼에 동일한 스크립팅 API와 경험을 제공합니다. 하지만 몇몇 플랫폼에는 각각 고유한 제약이 있습니다. 이러한 제약을 이해하도록 돕기 위해, 각각의 제약이 어떤 플랫폼과 스크립팅 백엔드에 적용되는지가 아래 표에 설명되어 있습니다.

플랫폼(스크립팅 백엔드) Ahead-of-time compile Supports threads
Android(IL2CPP) 지원 지원
Android(Mono) 지원 안 함 지원
iOS(IL2CPP) 지원 지원
Standalone(IL2CPP) 지원 지원
Standalone(Mono) 지원 안 함 지원
유니버설 Windows 플랫폼(IL2CPP) 지원 지원
WebGL(IL2CPP) 지원 지원 안 함

Ahead-of-time compile (AOT)

몇몇 플랫폼은 런타임 코드 생성을 지원하지 않습니다. 따라서 타겟 디바이스에서 JIT(just-in-time) 컴파일에 의존하는 일부 관리되는 코드는 작동하지 않습니다. 이 경우 관리되는 코드를 AOT(ahead-of-time) 방식으로 컴파일해야 합니다. 많은 경우 이러한 방식의 차이는 없지만, 몇몇 경우에서는 AOT 플랫폼을 사용할 때 몇 가지 고려해야 할 사항이 있습니다.

Reflection

Reflection is supported on AOT platforms. However if this compiler cannot infer that the code is used via reflection the code may not exist at runtime. See [[wiki:ManagedCodeStripping|Managed Code Stripping]] for more information.

System.Reflection.Emit

An AOT platform cannot implement any of the methods in the System.Reflection.Emit namespace.

직렬화

AOT 플랫폼은 반사를 사용하므로 직렬화와 역직렬화 문제가 생길 수 있습니다. 직렬화 또는 역직렬화의 일부인 반사를 통해서만 타입 또는 메서드가 사용되는 경우, AOT 컴파일러는 해당 타입이나 메서드가 필요로 하는 코드를 감지할 수 없습니다.

Generic Types and Methods

For generic types and methods the compiler must determine which generic instances are used because different generic instances may require different code. For example the code for List<int> is different than it is for List<double>. However IL2CPP will share code for usages for reference types, so the same code will be used for List<object> and List<string>.

It is possible to reference generic types and methods that IL2CPP did not find a compile time in the following cases:

  1. Creating a new generic instance at runtime: Activator.CreateInstance(typeof(SomeGenericType<>).MakeGenericType(someType));
  2. Invoking a static method on a generic instance: typeof(SomeGenericType<>).MakeGenericType(someType)).GetMethod("AMethod").Invoke(null, null);
  3. Invoking a static generic method: typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(someType).Invoke(null, null);
  4. Some calls to generic virtual functions that cannot be inferred at compile time.
  5. Calls with deeply nested generic value types. e.g. Struct<Struct<Struct<...<Struct<int>>>>.

To support those cases IL2CPP generates generic code that will work with any type parameter. However this code is slower because it can make no assumptions on the size of the type or if it is a reference or value type. If you need to ensure that faster generic methods are generated you do the following: * If the generic argument will always be a reference type, add the where: class constraint. Then IL2CPP will generate the fallback method using reference type sharing which causes no performance degradation. * If the generic argument will always be a value type, add the where: struct constraint. This enables some optimizations, but since the value types can be different sizes the code will still be slower. * Create a method named UsedOnlyForAOTCodeGeneration and add references to the generic types and methods you wish IL2CPP to generate. This method does not need (and probably shouldn’t) be called. The example below will ensure that a specialization for GenericType<MyStruct> will be generated.

public void UsedOnlyForAOTCodeGeneration()
{
    // Ensure that IL2CPP will create code for MyGenericStruct
    // using MyStruct as an argument.
    new GenericType<MyStruct>();

    // Ensure that IL2CPP will create code for SomeType.GenericMethod
    // using MyStruct as an argument.
    new SomeType().GenericMethod<MyStruct>();

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

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

Note that when the “Faster (smaller) builds” setting is enabled only the single fully sharable version of generic code is compiled. This reduces the number of methods generated, reducing compile time and build size, but comes at the expense of runtime performance.

네이티브 코드에서 관리되는 메서드 호출

네이티브 코드에서 호출될 수 있도록 C 함수 포인터로 마셜링해야 하는 관리되는 메서드는 AOT 플랫폼에서 몇 가지 제약 사항이 적용됩니다.

  • 관리되는 메서드는 정적 메서드여야 합니다.
  • 관리되는 메서드에는 [MonoPInvokeCallback] 속성이 있어야 합니다.
  • If the managed method is generic the [MonoPInvokeCallback(Type)] overload may be need to be used to specify the generic specializations that need to be supported. If so the type must be a generic instance with the correct number of generic arguments. It is possible to have multiple [MonoPInvokeCallback] attributes on a method as below:
// Generates reverse P/Invoke wrappers for NameOf<long> and NameOf<int>
// Note that the types are only used to indicate the generic arguments.
[MonoPInvokeCallback(typeof(Action<long>))]
[MonoPInvokeCallback(typeof(Action<int>))]
private static string NameOfT<T>(T item) 
{
    return typeof(T).Name;
}

스레드 없음

몇몇 플랫폼은 스레드를 지원하지 않으므로, System.Threading 네임스페이스를 사용하는 관리되는 코드는 런타임 도중 작동하지 않습니다. 또한, .NET 클래스 라이브러리의 일부분은 스레드에 암시적으로 의존합니다. 자주 사용되는 예제로는 System.Timers.Timer 클래스가 있는데, 이 클래스는 스레드 지원에 의존합니다.

예외 필터

IL2CPP supports exception filters, however the execution order filter statements and catch blocks is different because IL2CPP uses C++ exceptions to implement managed exceptions. This will not be noticeable unless a filter blocks writes to a field.

MarshalAs 및 FieldOffset 속성

IL2CPP는 런타임 시 MarhsalAsFieldOffset 속성의 반영을 지원하지 않으며, 이러한 속성을 컴파일 시점에 지원합니다. 적절한 플랫폼 호출 마셜링을 위해 이러한 속성을 사용해야 합니다.

동적 키워드

IL2CPP는 C# dynamic 키워드를 지원하지 않습니다. 이 키워드는 IL2CPP의 경우 불가능한 JIT 컴파일을 요구합니다.

Marshal.Prelink

IL2CPP는 Marshal.Prelink 또는 Marshal.PrelinkAll API 메서드를 지원하지 않습니다.

System.Diagnostics.Process API

IL2CPP doesn’t support the System.Diagnostics.Process API methods. For cases where this is required on desktop platforms, use the Mono scripting backend.

IL2CPP로 관리되는 스택 추적
관리되는 코드 스트리핑
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961