Ceras: Bug: Usage with generic Dictionary and larger boolean Arrays
Remember: The more faster I can reproduce your problem, the faster I can fix it 😛
Bug description
We are trying to use Ceras for serialization/deserialization of custom classes that have a generic Dictionary of kind Dictionary<string, object> to be able to exchange a bunch of arrays of different type over UDP with Unity from vvvv.
I coded a quick example that shows the basic idea of what we are trying to do: NSYNK/Ceras Issue.
Looks like when the dict has a too large array of booleans it throws the following exception:
System.Exception
HResult=0x80131500
Message=Cannot find type System.Single[] after searching in all user provided assemblies and all loaded assemblies. Is the type in some plugin-module that was not yet loaded? Or did the assembly that contains the type change (ie the type got removed)?
Source=Ceras
StackTrace:
at Ceras.SimpleTypeBinder.GetTypeFromBase(String baseTypeName)
at Ceras.Formatters.TypeFormatter.Deserialize(Byte[] buffer, Int32& offset, Type& type)
at Ceras.Formatters.ReferenceFormatter`1.Deserialize(Byte[] buffer, Int32& offset, T& value)
at Ceras.Resolvers.StandardFormatterResolver.KeyValuePairFormatter`2.Deserialize(Byte[] buffer, Int32& offset, KeyValuePair`2& kvp)
at Ceras.Formatters.CollectionFormatter`2.Deserialize(Byte[] buffer, Int32& offset, TCollection& value)
at Ceras.Formatters.ReferenceFormatter`1.Deserialize(Byte[] buffer, Int32& offset, T& value)
at Ceras.CerasSerializer.Deserialize[T](T& value, Byte[] buffer, Int32& offset, Int32 expectedReadLength)
at Ceras.CerasSerializer.Deserialize[T](T& value, Byte[] buffer)
at CerasDictionaryIssue.Program.TryWithCount(Int32 boolCount, Int32 floatCount) in E:\git\nsynk\CerasDictionaryIssues\CerasDictionaryIssue\Program.cs:line 30
at CerasDictionaryIssue.Program.Main(String[] args) in E:\git\nsynk\CerasDictionaryIssues\CerasDictionaryIssue\Program.cs:line 41
Propablly we are missusing Ceras or maybe we are missing a proper configuration of it? 🤔
How to reproduce the bug See simple example: NSYNK/Ceras Issue
Platform
- Ceras Version: 4.1.4 on net472
- We are using Unity version 2019.1.9f1, but not IL2CPP
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 17 (12 by maintainers)
The quick fix likely won’t work reliably, but it only hast to work for a few more hours. I’ll be able to start working on my ideas to fix this at around 15:00 today (german time).
Also seems like the compare methods themselves are not the problem, but rather a bug in the ‘Encoding’ class of .NET (I’ll update my previous post with more info on that later…)
Thanks for your patience 😛 😄
So what is the actual root cause for the bug you found @guidoschmidt ?
It seems (and that’s just a guess) that
Assembly.GetTypealso usesstring.Equals,string.CompareOrdinal(), or another copy that has a similar bug.So what does that mean for Ceras?
I sure yet, It seems to literally be a bug in .NET Framework. I don’t know if I can make a workaround for it, or how that would look like? (maybe string interning could help?)
Maybe strings are supposed to have
\0\0at the end? But looking at my “literal” string in the memory view doesn’t show it ending with that either.Super awesome 🎉 I’ll try the fix tomorrow and report back here. Thanks again for all the effort you put into this (from the whole team at NSYNK). Your quick and competent help is well appreciated.
As expected, it turned out not a bug in .NET, but instead a (very) well hidden one in Ceras. For various reasons
Marshal.SizeOfreports the size of a bool to be 4, whileUnsafe.SizeOfreports 1.The issue is fixed with f8d4db31a33397ba5c9d3f24189e59ce363e5580 and the v4.1.6 compiled from that is pushed to nuget. 😄
Feel free to reopen when needed (or just create a new issue)! 👍
Hi, just had 5 free minutes to check it out. I can’t reproduce it on the
masterbranch!Can you retry it using the latest commit? Also: When using Ceras in Unity, I strongly suggest you use the source code. In the past my advice was to use the precompiled dlls, but that has changed for various reasons.
I’ve updated the guide just a few days ago (probably too basic for you, but I just thought I’d mention it in case anything is unclear 😃 ). Usage with Unity Guide
Or is there something I’m missing maybe? I’m able to let all the 4 calls run though without the exception: https://i.imgur.com/SLyN0Ht.png