Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is serializing double[] not working in WinCE?

I have an Object with (de-)serializes its configuration via system.xml.serializer

The config is in a class looking like this:

    public struct Phase
    {
        public Int16 Trafo;
        public KorrekturWerte Spannung;
        public KorrekturWerte Strom;
        [XmlArray("Min")]
        public double[] Min;
        [XmlArray("Max")]
        public double[] Max;
        public bool CheckThis;
    }

    public class ParameterHardware
    {
        public string WAGOId = "00:30:DE:05:33:CB";
        public Byte Phasen = 0x07;
        public Phase L1;
        public Phase L2;
        public Phase L3;
    }

(De-)Serializing this on a WindowsXP-System works just fine, but on Windows CE, the Min/Max-Array is just mussing after de- and then reserializing ("CheckThis" was put there as a test and follows after serializing the "Strom" values). As KorrekturWerte is again a struct, depth can't be the problem. The [XmlArray ...] wasn't there in my first version, it's just from another test.

Edit:

  • The Problem is not (only) in serialization. Trying to access Min[...] I get a null reference error.

  • Maybe it's not clear: I have a serialization of the class, which contains all values. Deserialize it to initialize the class and then reserialize it as a debug-check. Now the fields are missing. (The original file was serialized in XP, where it works all right)

  • Changeing the double[] to List does not help. (Same result)

  • The xml-files: Original:

    00:30:DE:05:53:65 1 50 -0.2 1 0.004 0.994 0 0 0 0 0 500 32 15000 15000 1 true 50 0 1 0 1 0 0 0 0 0 500 32 15000 15000 1 50 0 1 0 1 0 0 0 0 0 500 32 15000 15000 1

Reserialization (sorry, CE serializes in one single line):

<?xml version="1.0" encoding="utf-8"?><ClassTest_FCT_Extern xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Hardware><WAGOId>00:30:DE:05:53:65</WAGOId><Phasen>1</Phasen><L1><Trafo>50</Trafo><Spannung><Offset>-0.2</Offset><Steigung>1</Steigung></Spannung><Strom><Offset>0.004</Offset><Steigung>0.994</Steigung></Strom><CheckThis>true</CheckThis></L1><L2><Trafo>50</Trafo><Spannung><Offset>0</Offset><Steigung>1</Steigung></Spannung><Strom><Offset>0</Offset><Steigung>1</Steigung></Strom><CheckThis>false</CheckThis></L2><L3><Trafo>50</Trafo><Spannung><Offset>0</Offset><Steigung>1</Steigung></Spannung><Strom><Offset>0</Offset><Steigung>1</Steigung></Strom><CheckThis>false</CheckThis></L3></ClassTest_FCT_Extern>
  • Sorry for bringing everything slice by slice. Here is the serialization code (using System.Xml.Serialization;)

    try
    {
        fstream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
        reader = new XmlTextReader(fstream);
        serializer = new XmlSerializer(typeof(T));
        retobj = (T)serializer.Deserialize(reader);
    }
    catch (Exception e)
    {
        Debug("Serialization: "+e.ToString());
        retobj = Activator.CreateInstance<T>();
     }
    

Debug is not called, so there don't seem to be any errors.

  • The .net Version is 2.0
like image 982
Nikodemus RIP Avatar asked Feb 21 '23 08:02

Nikodemus RIP


2 Answers

Your min/max array must be initialized with new double[] or its null and you have nullref exceptions and missing fields. Null values are not serialized and are missing.

Edit2:

Seems like there is a problem deserializing arrays/lists for you. Please make the tag names of the array items more explicite like this:

  [XmlArray("Min")]
  [XmlArrayItem("Value")]
  public double[] Min;
  [XmlArray("Max")]
  [XmlArrayItem("Value")]
  public double[] Max;

and try if that helps you.

Edit3

From what you described in our discussion and chat you must have encountered a real bug in .NET Compact Framework 2.0.

So propably your best bet is to use a custom Deserializer under CE, if you can't update the Framework.

There were also some other bugs reported under CE here.

like image 80
BlueM Avatar answered Feb 24 '23 02:02

BlueM


Searching for other (working) solutions, I finally discovered a difference between them and my approach. I had a public double[] or then in some tests a public List. All the other solutions had a privat List<> and then a public getter. (Which is enough for a List<> to serialize). Changeing my struct phase accordingly, everything works now fine:

public class Phase
{
    public Int16 Trafo = 50;
    public KorrekturWerte Spannung = new KorrekturWerte() { Offset = 0, Steigung = 1 };
    public KorrekturWerte Strom = new KorrekturWerte() { Offset = 0, Steigung = 1 };
    private List<double> m_Min = new List<double>();
    private List<double> m_Max = new List<double>();
    public List<double> Min { get { return m_Min; } }
    public List<double> Max { get { return m_Max; } }
    //public double[] Default;
}
like image 41
Nikodemus RIP Avatar answered Feb 24 '23 01:02

Nikodemus RIP