applejag/Newtonsoft.Json-for-Unity

DLLs built in Visual Studio not working on UWP IL2CPP

eirikhollis opened this issue · 5 comments

In the project I'm currently working on, I need to add packages to the project as DLLs instead of using UPM. I've tested the project with using UPM and it runs successfully in Unity 2019.3.4f1, UWP x86, and UWP ARM.

I cloned the project in Visual Studio 2019 v16.4.5, installed the required .NET Framework packages and .NET Core 3.0.100 SDK found here. When building for the first time, I need to build twice, probably since the build order of the projects are not setup correctly.

I end up with these three folders:
image
which each contains a Newtonsoft.Json.dll and a Newtonsoft.Json.pdb file.

When added to Unity 2019.3.4f1, I configured the DLL from unity-editor folder to work with Unity and the DLL from the unity-portable-net45 to work with UWP (x86, x64, ARM, ARM64). The Api Compatibility Level parameter is set to .NET Standard 2.0.
image

However, when testing with UWP x86 and UWP ARM, serialization/deserialization does not work.
image
image

Call Stack:

>	Func`2 Newtonsoft.Json.Utilities.ExpressionReflectionDelegateFactory:CreateGet (PropertyInfo)+0x8a at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\Utilities\ExpressionReflectionDelegateFactory.cs:[252:13-252:86]	C#
 	Func`2 Newtonsoft.Json.Utilities.ReflectionDelegateFactory:CreateGet (MemberInfo)+0x2f at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\Utilities\ReflectionDelegateFactory.cs:[49:17-49:51]	C#
 	Object Newtonsoft.Json.Serialization.ExpressionValueProvider:GetValue (Object)+0x14 at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\Serialization\ExpressionValueProvider.cs:[108:21-108:107]	C#
 	Boolean Newtonsoft.Json.Serialization.JsonSerializerInternalWriter:CalculatePropertyValues (JsonWriter, Object, JsonContainerContract, JsonProperty, JsonProperty, JsonContract, Object)+0x67 at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:[540:17-540:71]	C#
 	Void Newtonsoft.Json.Serialization.JsonSerializerInternalWriter:SerializeObject (JsonWriter, Object, JsonObjectContract, JsonProperty, JsonContainerContract, JsonProperty)+0x47 at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:[470:21-470:152]	C#
 	Void Newtonsoft.Json.Serialization.JsonSerializerInternalWriter:SerializeValue (JsonWriter, Object, JsonContract, JsonProperty, JsonContainerContract, JsonProperty)+0xc1 at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:[181:21-181:133]	C#
 	Void Newtonsoft.Json.Serialization.JsonSerializerInternalWriter:Serialize (JsonWriter, Object, Type)+0x4e at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalWriter.cs:[81:21-81:83]	C#
 	Void Newtonsoft.Json.JsonSerializer:SerializeInternal (JsonWriter, Object, Type)+0x243 at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\JsonSerializer.cs:[1149:13-1149:90]	C#
 	Void Newtonsoft.Json.JsonSerializer:Serialize (JsonWriter, Object, Type)+0x4 at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\JsonSerializer.cs:[1049:13-1049:62]	C#
 	String Newtonsoft.Json.JsonConvert:SerializeObjectInternal (Object, Type, JsonSerializer)+0x2c at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\JsonConvert.cs:[665:17-665:67]	C#
 	String Newtonsoft.Json.JsonConvert:SerializeObject (Object, Type, JsonSerializerSettings)+0xa at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\JsonConvert.cs:[614:13-614:73]	C#
 	String Newtonsoft.Json.JsonConvert:SerializeObject (Object)+0x3 at D:\Newtonsoft.Json-for-Unity\Src\Newtonsoft.Json\JsonConvert.cs:[530:13-530:80]	C# 

Are any of the steps I do wrong somehow?

Hi! Very nice issue!

I've never thoroughly tested the UWP builds. Looks like there's something properly misconfigured in the Newtonsoft code.

I'm currently down with the sickness and cannot investigate this until that passes (corona ftw). In the meantime you could check if you could use the AOT build in your UWP release instead, that one should be pretty universal anyway.

Thanks for the quick response!
Sorry to hear you are sick, hope you get better soon.

When you say to use the AOT build on UWP, do you mean the DLL/PDB located in the unity-editor folder?

No sorry, the AOT is built when having the UnityBuild flag set to "AOT". One way to achive this is by using the build script /ci/local_build_into_package.ps1 that will build the AOT DLLs into /Src/Newtonsoft.Json-for-Unity/Plugins/Newtonsoft.Json AOT/*

I've only recently been studying some MSBuild mechanics so this can be built automatically when running build in Visual Studio, but not had the time to implement it yet. When I develop locally for this project I use a lot of scripts to build inside Docker containers for the maximum repeatability. I see now that this may be ambiguous from the "Build" section of the README.md.

Finally got the time to test it. Worked on UWP x86 but not on UWP ARM. Difficult to debug at the moment on ARM, so I don't have any detailed exception report for you.

Any ideas?

You might get some tips on how to debug UWP ARM here: https://docs.unity3d.com/Manual/windowsstore-deployment.html. I hope it gives a different exception than the one you posted in the issue body as that one comes from an exception inside ExpressionReflectionDelegateFactory, which should be omitted in AOT builds.

I am unsure which UWP version you're using, but looking at the following matrix we see that if you have at least UWP v10.0.16299 then the .NET Standard 2.0 variant of Newtonsoft.Json should be fine: https://github.com/dotnet/standard/blob/master/docs/versions.md