At this point in time, the plugin model for Windows Store with IL2CPP scripting backend is much more similar to other Unity platforms (such as Windows standalone), rather than Windows Store with .NET scripting backend.
Unlike .NET scripting backend, IL2CPP scripting backend does not support managed plugins targeting .NET 4.5 or any of Windows Runtime APIs. All managed plugins must be targeting .NET 3.5 or equivalent API.
Another difference compared to .NET scripting backend is that IL2CPP scripting backend exposes the exact same .NET API surface as Unity editor or standalone player, so it’s possible to use the same plugins without the need to compile separate versions target different .NET API for Windows Store.
IL2CPP 스크립팅 백엔드는 플랫폼 호출 메커니즘을 통해 네이티브 플러그인 사용을 지원합니다. 따라서 네이티브 함수 프로토타입을 지정한 후 이를 호출하는 방법으로 네이티브 플러그인을 직접 C# 코드에서 호출할 수 있습니다. 아래의 예제를 참조하십시오.
[DllImport("MyPlugin.dll")]
private static extern int CountLettersInString([MarshalAs(UnmanagedType.LPWSTR)]string str);
private void Start()
{
Debug.Log(CountLettersInString("Hello, native plugin!"));
}
MyPlugin.dll에서 이러한 함수의 구현은 아래와 같이 이루어집니다.
extern "C" __declspec(dllexport)
int **stdcall CountLettersInString(wchar_t* str)
{
int length = 0;
while (*str++ != nullptr)
length++;
return length;
}
플랫폼 호출 마셜링 규칙은 공식 .NET 마셜링 규칙과 동일합니다만, 아래와 같이 몇몇 지원되지 않는 타입이 있습니다.
The default calling convention for P/Invoke functions on x86 is **stdcall
.
네이티브 플러그인은 미리 컴파일된 DLL이나 C++ 소스 코드를 통해 작성할 수 있습니다.
미리 컴파일된 네이티브 플러그인에 플랫폼 호출을 하는 과정은 런타임 중 DLL를 로드하고, 함수 입력 지점을 검색한 후 호출하는 방법으로 이루어집니다. 이들 DLL 파일은 타겟 CPU 아키텍처에 대한 올바른 Windows SDK에 대해 컴파일되어야 합니다. 또한 Unity 프로젝트에 추가되는 경우 플러그인 인스펙터에서 설정해야 합니다.
It is possible to add C++ (.cpp) code files directly into Unity project, which will act as a plugin in Plugin Inspector. If configured to be compatible with Windows Store and IL2CPP scriping backend, these C++ files will be compiled together with C++ code that gets generated from managed assemblies:
함수들은 생성된 C++ 코드와 연결되어 있으므로 플랫폼 호출을 진행할 별도의 DLL 파일은 없습니다. 이런 이유로 DLL 이름 대신 “__Internal” 키보드를 사용할 수 있으며, 이 경우 아래와 같이 런타임 시점에 함수를 로드하는 대신 C++ 링커가 함수를 해결하는 책임을 집니다.
[DllImport("__Internal")]
private static extern int CountLettersInString([MarshalAs(UnmanagedType.LPWSTR)]string str);
호출은 링커에 의해 해결되므로, 관리된 부분의 함수 선언에서 오류가 발생하면 런타임 오류가 아닌 링커 오류가 발생합니다. 또한 런타임 중에 동적 로딩이 발생하지 않으며, 함수가 직접 호출됩니다. 이로 인하여 플랫폼 호출의 부하가 상당히 줄어들게 됩니다.
On Windows Store you cannot P/Invoke into specific system libraries by specifying the dll name (like “kernelbase.dll”) when using IL2CPP scripting backend. Attempting to P/Invoke into any DLL that exists outside of the project will result in DllNotFoundException at runtime.
하지만 DLL 이름 대신 “Internal” 키워드를 지정하여 시스템 함수에 대해 플랫폼 호출을 할 수 있습니다. 이렇게 되면 빌드 타임 동안 링커가 함수를 해결하게 됩니다.