Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Microsoft.SPOT.Reflection.Serialize() / Deserialize() throws System.NotImplementedException


  • Please log in to reply
25 replies to this topic

#1 Fabien Royer

Fabien Royer

    Advanced Member

  • Members
  • PipPipPip
  • 406 posts
  • LocationRedmond, WA

Posted 13 January 2011 - 01:27 AM

Hi,

I was hoping to use the native serialization / deserialization support of the framework to save / load / marshall object state. However, it appears that such functions aren't implemented.

using System;
using System.IO.Ports;
using System.Threading;
using Microsoft.SPOT;
using SecretLabs.NETMF.Hardware.Netduino;

namespace Serializer
{
    public class Program
    {
        public static void Main()
        {

            int i = 0;

             var buffer = Reflection.Serialize(i, i.GetType());
        }
    }
}

The thread '<No Name>' (0x2) has exited with code 0 (0x0).
#### Exception System.NotImplementedException - 0xca000000 (1) ####
#### Message:
#### Microsoft.SPOT.Reflection::Serialize [IP: 0000] ####
#### Serializer.Program::Main [IP: 0011] ####
A first chance exception of type 'System.NotImplementedException' occurred in Microsoft.SPOT.Native.dll
An unhandled exception of type 'System.NotImplementedException' occurred in Microsoft.SPOT.Native.dll

Are there plans to port this to the netduino framework in the future?

Cheers,
-Fabien.

#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 13 January 2011 - 02:47 AM

Hi Fabien, I believe that serialization support would be pretty big. We can look into adding it (or you can add it in the open source code if available)...but my guess is that it'd be too big for small micros. Chris

#3 Fabien Royer

Fabien Royer

    Advanced Member

  • Members
  • PipPipPip
  • 406 posts
  • LocationRedmond, WA

Posted 13 January 2011 - 08:02 PM

Thanks Chris. Sounds like an opportunity to roll-out a lightweight version to me ;-) There may already be one out there actually... Cheers, -Fabien.

#4 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 13 January 2011 - 10:28 PM

building a lightweight serializer wouldnt be too hard, I have some old source that could work, its optimistic and only handles simple objects. I will more than likely be re-visiting it soon in my quad project. What are you wanting to serialize (what types of objects)?

#5 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 13 January 2011 - 10:34 PM

Chris are the interfaces there to be implemented? IFormatter etc http://codebetter.co...-serialization/ old but still works

#6 Fabien Royer

Fabien Royer

    Advanced Member

  • Members
  • PipPipPip
  • 406 posts
  • LocationRedmond, WA

Posted 13 January 2011 - 10:51 PM

building a lightweight serializer wouldnt be too hard, I have some old source that could work, its optimistic and only handles simple objects. I will more than likely be re-visiting it soon in my quad project. What are you wanting to serialize (what types of objects)?



I agree: it is fairly simple to write.

Basically, I want to binary-serialize / deserialize the ValueTypes and some of the objects found in the System namespace.
Generally, any 'object' type would be handled through recursive reflection, looking within each object for System ValueTypes and System objects supported by the custom serializer.
Collections of objects would also need to be supported (ArrayList, Hashtable, Queue, Stack) according to the same reflection mechanics.

Does this make sense?

#7 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 13 January 2011 - 11:02 PM

i think if we just did value types and collections of value types with recursion of more complex obecjts as long as they were all inheriting the same interface to start we could open it up from there, i'm new here and wondering if you guys have a svn or git repository going yet? if not I could host something up on mine if need be. Hopefully if i can help on the code side you guys can scratch my back a bit on the hardware side

#8 Fabien Royer

Fabien Royer

    Advanced Member

  • Members
  • PipPipPip
  • 406 posts
  • LocationRedmond, WA

Posted 14 January 2011 - 12:22 AM

Yes, that sounds like a good starting point :)


After doing some research, I found this thread: http://codebetter.co...-serialization/ pointing to various implementations
and this one on wire data: http://msdn.microsof...e/cc163960.aspx (which is funny because Xbox LIVE is my team and we're still using this method!)

So, there are many existing solutions out there, but it is unclear yet if they work under the netduino's implementation of the .Net Micro Framework...

As far as a repository goes, I'm planning on integrating this to the netduino.helpers library: http://netduinohelpers.codeplex.com/

Cheers,
-Fabien.

#9 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 14 January 2011 - 01:23 AM

Wow, Fabien... I didn't realize that XBox Live was based off of ASP.NET. That's awesome (and makes a lot of sense). The Netduino implementation of .NET MF is the core one provided in the .NET MF porting firmware with some enhancements (variable-bit PWM, I2C repeated start bit, analog inputs, PWM, etc. etc.) We have some room in flash to add a few features. If serialization can be added without taking up much room, we might be able to fit it on the chip; and if not, perhaps a managed-code version from your netduino.helpers library can be deployed at runtime. Thanks for all your contributions, Fabien. Chris

#10 Fabien Royer

Fabien Royer

    Advanced Member

  • Members
  • PipPipPip
  • 406 posts
  • LocationRedmond, WA

Posted 14 January 2011 - 01:56 AM

Wow, Fabien... I didn't realize that XBox Live was based off of ASP.NET. That's awesome (and makes a lot of sense).

The Netduino implementation of .NET MF is the core one provided in the .NET MF porting firmware with some enhancements (variable-bit PWM, I2C repeated start bit, analog inputs, PWM, etc. etc.) We have some room in flash to add a few features. If serialization can be added without taking up much room, we might be able to fit it on the chip; and if not, perhaps a managed-code version from your netduino.helpers library can be deployed at runtime.

Thanks for all your contributions, Fabien.

Chris


It's a mix of ASP.Net, the standard .Net Framework and some C++ where applicable :)

I agree with you: it should only be added to the core framework if it doesn't take much room since there are lightweight alternatives which can be deployed only as needed. I'm curious to hear what your dev team thinks...

...and you're welcome :)

Cheers,
-Fabien.

#11 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 14 January 2011 - 03:44 AM

greg and i worked together for 5 years that initial implementation was ours, albeit naive it suited our purposes. They are all teeny, almost any well written serialization implementations will be, i'd love to help out.

#12 Fabien Royer

Fabien Royer

    Advanced Member

  • Members
  • PipPipPip
  • 406 posts
  • LocationRedmond, WA

Posted 14 January 2011 - 07:52 AM

Brandon, That's great news! I'd love for you to contribute to the netduino.helpers library with your lightweight serialization class. Go for it! Let me know when you have something that I can test and I'll integrate it. Are you OK releasing it under the MIT license? And of course, you get the credit! Cheers, -Fabien.

#13 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 14 January 2011 - 04:41 PM

Not a problem, will be a couple weeks before i can start but look forward to it

#14 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 01 February 2011 - 01:20 AM

So i started to get into it and I have come across some road blocks and cant seem to find a way around it. Reflection being limited i cant even call CreateInstance() or the other method i had up my sleeve FormatterServices.GetUninitializedObject() or Activator.CreateInstance, is there anyway to initialize an object from a string at all in netmf, otherwise i think we're shit out of luck short of some ugly case statements

#15 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 01 February 2011 - 04:06 AM

is there anyway to initialize an object from a string at all in netmf

Does this help?

using System;
using Microsoft.SPOT;

namespace NetduinoApplication14 {
  public class Program {
    public static void Main() {
      var z=Type.GetType("NetduinoApplication14.Zamboni").GetConstructor(new Type[0]).Invoke(new object[0]);
    }
  }

  public class Zamboni {
    public Zamboni() {
      Debug.Print("Inside constructor");
    }
  }
}


#16 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 01 February 2011 - 04:34 PM

i ended up finding that shortly thereafter, thanks Corey. I've stubbed out the whole thing just going for some optimization now. My current application for it is the quadrocopter so has to be heavily optimized and optimistic, a more generic library can be made off it after, will post when done

#17 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 02 February 2011 - 05:18 AM

Heres a very prelim write of this with some simple implementations as you can see i am putting the responsibility on the ISerializable object for now, not a full object graph, as i extend this i will update, right now its pretty ugly and specific


EDIT: didnt like what i posted earlier, here`s a revamp
using Quad.Net.Commons.Serialization;

namespace Quad.Net.Commons.Logging
{
    public interface ILogger
    {
        void Flush();
        void Write(ISerializable obj);
    }
}

using System.IO;
using Quad.Net.Commons.Serialization;

namespace Quad.Net.Commons.Logging
{
    public class PersistenceWriter : ILogger
    {
        private readonly IBinaryFormatter _formatter;
        private readonly string _fileName;
        private readonly FileStream _fileStream;

        public PersistenceWriter(string fileName, IBinaryFormatter formatter)
        {
            _formatter = formatter;
            _fileName = fileName;
            _fileStream = new FileStream(_fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 512);
        }

        public void Flush()
        {
            _fileStream.Flush();
        }

        
        public void Write(ISerializable obj)
        {
            _formatter.Serialize(_fileStream, obj);

        }
    }
}


using System.IO;
using Quad.Net.Commons.Serialization;

namespace Quad.Net.Commons.Logging
{
    public class PersistanceReader
    {
        private readonly IBinaryFormatter _binaryFormatter;

        public PersistanceReader(IBinaryFormatter binaryFormatter)
        {
            _binaryFormatter = binaryFormatter;
            
        }
        public ISerializable[] GetMessages(string readPath)
        {
            FileStream readFile = new FileStream(readPath, FileMode.Open, FileAccess.Read);
            return _binaryFormatter.Deserialize(readFile);
        }
    }
}

using System;
using System.IO;

namespace Quad.Net.Commons.Serialization
{
    public interface IBinaryFormatter
    {
        void Serialize(Stream stream, Object graph);//not implemented
        ISerializable[] Deserialize(Stream stream);
        void Serialize(Stream stream, ISerializable graph);//optimistic
    }
}


namespace Quad.Net.Commons.Serialization
{
    public interface ISerializable //:  where T : new() in classic C# this is what i would do force a parameterless contructor, cant do thisin netmf
    {
        byte[] Serialize();
        object Deserialize(byte[] buffer);
    }
}

using System;
using System.Collections;
using System.IO;

namespace Quad.Net.Commons.Serialization
{
    public class TelemetryFormatter:IBinaryFormatter
    {
        public void Serialize(Stream stream, object graph)
        {
            throw new NotImplementedException();
        }

        public ISerializable[] Deserialize(Stream stream)
        {
            ISerializable[] items = new ISerializable[stream.Length/44];
            int counter = 0;
            while (stream.Position < stream.Length)
            {
                byte[] buffer = new byte[44];
                stream.Read(buffer, 0, 44);
                ISerializable item  = (ISerializable) typeof(TelemetryData).GetConstructor(new Type[0]).Invoke(new object[0]);
                item.Deserialize(buffer);
                items[counter] = item;
                counter++;
            }
            return items;
        }

        public void Serialize(Stream stream, ISerializable graph)
        {
            byte[] buffer = graph.Serialize();
            stream.Write(buffer, 0, buffer.Length);
        }
    }
}


using System;
using Microsoft.SPOT.Hardware;
using Quad.Net.Avionics;
using Quad.Net.Commons.Serialization;
using Quad.Net.Commons.Utilities;

namespace Quad.Net.FlightController
{
    public class TelemetryData : ISerializable
    {
        private readonly AircraftPrincipalAxes  _gyroAxes;
        private readonly AircraftPrincipalAxes _radioAxes;
        private readonly AircraftPrincipalAxes _pidAxes;
        private long _currentTime;
        private readonly byte[] _buffer;
        public TelemetryData()
        {
            _gyroAxes= new AircraftPrincipalAxes(0,0,0);
            _radioAxes = new AircraftPrincipalAxes(0, 0, 0);
            _pidAxes = new AircraftPrincipalAxes(0, 0, 0);
            _currentTime = DateTime.Now.Ticks;
            _buffer = new byte[44];
        }

        public void Update(AircraftPrincipalAxes gyroAxes, AircraftPrincipalAxes radioAxes, AircraftPrincipalAxes pidAxes, long currentTime)
        {
            _gyroAxes.Update(gyroAxes.Pitch,gyroAxes.Roll,gyroAxes.Yaw);
            _radioAxes.Update(radioAxes.Pitch, radioAxes.Roll, radioAxes.Yaw);
            _pidAxes.Update(pidAxes.Pitch, pidAxes.Roll, pidAxes.Yaw);
        }

        public byte[] Serialize()
        {
            Utility.InsertValueIntoArray(_buffer, 0, 4, (uint)(_currentTime >> 32));
            Utility.InsertValueIntoArray(_buffer, 4, 4, (uint)_currentTime);
            Utility.InsertValueIntoArray(_buffer, 8, 4, (uint)_gyroAxes.Pitch);
            Utility.InsertValueIntoArray(_buffer, 12, 4, (uint)_gyroAxes.Roll);
            Utility.InsertValueIntoArray(_buffer, 16, 4, (uint)_gyroAxes.Yaw);

            Utility.InsertValueIntoArray(_buffer, 20, 4, (uint)_radioAxes.Pitch);
            Utility.InsertValueIntoArray(_buffer, 24, 4, (uint)_radioAxes.Roll);
            Utility.InsertValueIntoArray(_buffer, 28, 4, (uint)_radioAxes.Yaw);

            Utility.InsertValueIntoArray(_buffer, 32, 4, (uint)_pidAxes.Pitch);
            Utility.InsertValueIntoArray(_buffer, 36, 4, (uint)_pidAxes.Roll);
            Utility.InsertValueIntoArray(_buffer, 40, 4, (uint)_pidAxes.Yaw);
            return _buffer;
        }

        public object Deserialize(byte[] buffer)
        {
            _currentTime = BitConverter.ToLong(buffer, 0);
            _gyroAxes.Update(
                Utility.ExtractValueFromArray(buffer, 8, 4),
                Utility.ExtractValueFromArray(buffer, 12, 4),
                Utility.ExtractValueFromArray(buffer, 16, 4)
                );
            _radioAxes.Update(
                Utility.ExtractValueFromArray(buffer, 20, 4),
                Utility.ExtractValueFromArray(buffer, 24, 4),
                Utility.ExtractValueFromArray(buffer, 28, 4)
                );
            _pidAxes.Update(
                Utility.ExtractValueFromArray(buffer, 32, 4),
                Utility.ExtractValueFromArray(buffer, 36, 4),
                Utility.ExtractValueFromArray(buffer, 40, 4)
                );
            return this;
        }

        public override string ToString()
        {
            //csv format
            return _currentTime + "," +
                   _gyroAxes.Pitch + "," +
                   _gyroAxes.Roll + "," +
                   _gyroAxes.Yaw + "," +
                   _radioAxes.Pitch + "," +
                   _radioAxes.Roll + "," +
                   _radioAxes.Yaw + "," +
                   _pidAxes.Pitch + "," +
                   _pidAxes.Roll + "," +
                   _pidAxes.Yaw + ",";
        }
    }
}



#18 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 02 February 2011 - 05:20 AM

oh and i havent written tests for it yet, once i have and made this a little more generic i will psot as a zip

#19 Fabien Royer

Fabien Royer

    Advanced Member

  • Members
  • PipPipPip
  • 406 posts
  • LocationRedmond, WA

Posted 02 February 2011 - 07:09 AM

Awesome Brandon :) I'll be glad to help you test it as well. Cheers, -Fabien.

#20 Brandon G

Brandon G

    Advanced Member

  • Members
  • PipPipPip
  • 92 posts
  • LocationVancouver BC, Canada

Posted 02 February 2011 - 04:15 PM

updated above, as i said this a very very specific and optimistic serialization system for my exact purposes, but the idea is sound and could be used in other places, u merely have to implement ISerializable on your class and insert a type into the serialize message in order to dynamically invoke the constructor, i know i am in this instance only serializing one type with this formatter so i have put that statically in, you could easily put in a header to accomplish this such as stx....type...data...etx once you know your type merely parse and dynamically invoke and assume T : new()




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.