Search Unity

Question Managed Plugin Unresolved System.ValueTuple On Build

Discussion in 'Windows' started by marudge, Feb 10, 2023.

  1. marudge

    marudge

    Joined:
    Apr 25, 2019
    Posts:
    7
    We have imported a managed plugin into Unity 2021.3 LTS for a UWP project. We have the API compatibility level set to .NETStandard 2.1 in Player settings. We are running into a build error with that plugin where the Unity linker can’t resolve the Item2 field on System.ValueTuple.

    According to the Unity documentation here:

    “By default, IL2CPP targets .NET 2.0 API compatiblity level. That means it does not support managed plugins targeting .NET 4.5 or consuming any of Windows Runtime APIs. All managed plugins must be targeting .NET 4.5 or equivalent API when using this compatiblity level. You can switch to .NET 4.6 API compatibilty level in Player settings if you wish to lift these restrictions.”

    This statement is confusing to me as the second and third sentence seem to contradict each other. Regardless, I have tried switching the API compatibility level between .NET Framework and .NET Standard 2.1, but both fail with the same exception (attached to thread). Interestingly, ValueTuple does resolve and work fine in C# scripts.

    My assumption at this time is that this structure simply won’t work in a managed plugin, but I would love confirmation of that and some more understanding on what the restrictions are for managed plugins. It would also be great to understand if there is an alternative way to consume this managed plugin, such as referencing it from the generated solution instead of putting it through Unity's build process.

    Thank you for your help and time.
     

    Attached Files:

    Hunter_MSFT likes this.
  2. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    How did you compile your managed assembly? I can imagine this could happen if you compiled it against .NET Core or some variant of it instead of against .NET Standard 2.0 or 2.1 or .NET framework 4.5. It's a bit hard to know what's going on without seeing that managed plugin myself.

    Disregard what that documentation link says. We're in the process of rewriting it... it's about 5 years out of date. Unity doesn't even allow you to target .NET 2.0 anymore.
     
  3. marudge

    marudge

    Joined:
    Apr 25, 2019
    Posts:
    7
    The assembly was created to be a plugin for UWP, so, like UWP, the assembly is compiled against a .NET Core variant.

    Our target platform is UWP for our application. What sort of options do we have to get around this issue and still utilize the unmodified plugin with our application?
     
  4. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Without having access to that managed plugin itself, it's hard to tell what's going wrong with it. I assume you aren't able to share it with me? Can you at least extract the IL code from the function it's complaining about (the name you redacted) using ILSpy (or similar)?

    Do you know exactly what framework the plugin is compiled against? In Unity, we test these:

    • .NET Framework 4.8
    • .NET Standard 2.0
    • .NET Standard 2.1
    • UniversalWindowsPlatform, v5.2.2 (only when targeting UWP - this was the last version of .NET Core we supported before dropping it and thus the last version that we expect people to build plugins against when using them in Unity).
     
  5. marudge

    marudge

    Joined:
    Apr 25, 2019
    Posts:
    7
    Thanks for your replies! No, I cannot share the plugin with you unfortunately. The UniversalWindowPlatform version in use is 6.2.14. UniversalWindowPlatform 5.2.2 is unfortunately very old and also has high security vulnerabilities.

    I believe it is complaining about code similar to this in the plugin:
    Code (CSharp):
    1. (T obj, bool isActive)[] array = new (T obj, bool isActive)[totalSize];
    2. for (int index = 0; index < totalSize; ++index)
    3. {
    4.     array[index].isActive = false;
    5. }
     
  6. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    IL code would contain which assembly it tries to reference System.ValueTuple from. Unfortunately you cannot see it in C# code.

    Anyway, I think the only way forward for you is to recompile the plugin against .NET Standard 2.0 or 2.1 - that will make it compatible with both Unity and UWP. We don't support plugins targeting 6.x version of UniversalWindowsPlatform.

    You could also report a bug to us with a sample plugin that's compiled the same way as the one you cannot share that reproduces this issue. We could see if we are able to fix it easily but I can give you no guarantees of that. This would also take at least a couple months due to how we prioritize the bug backlog.
     
  7. marudge

    marudge

    Joined:
    Apr 25, 2019
    Posts:
    7
    Thanks for the reply. I wouldn't expect Unity to fix this particular issue. I was trying to understand what the limitations are when it comes to managed plugins. And I think I understand more now what the issue is thanks to your responses.

    The managed plugin is a Windows Runtime Component (winmd) that is created to be used as a UWP library. When you create one of these in Visual Studio 2022, it sets the UniversalWindowsPlatform as 6.2.14 and the target platform as .NET Core 5.0. In .NET Core 5.0, ValueTuple is in the System.Runtime assembly, compared to .NET Framework 4.8 (mscorlib) and .NET Standard 2.0/2.1 (netstandard).

    To recap then, imported managed plugins should be compiled against .NET Framework 4.8 or .NET Standard 2.0/2.1. I wouldn't recommend UniversalWindowsPlatform 5.2.2 given the reasons I stated in this thread.

    Thanks so much for your help.
     
  8. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Thanks for the update and a nice summary!