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)

Most upvoted comments

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.GetType also uses string.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\0 at 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.SizeOf reports the size of a bool to be 4, while Unsafe.SizeOf reports 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 master branch!

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