I thought I had serialization licked but apparently not. I have one program that 1) creates some data (including 2 structures) in a class and serializes the class into a byte array, 2) deserializes the array so I can check what came out is the same as what went in, 3) writes the byte array to a file on the SD card and 4) reads the file and deserializes so I can check what got written to the file is the same as what I started with.
That program works OK and all my deserialize checks look like the original data.
When I try to run a separate program that has the same class definition and uses the same method to read from the file and deserialize, I get an "Unknown type exception when it tries to deserialize.
Any suggestions will be greatly appreciated since getting serialize/deserialize to work would be kind of a silver bullet for my current app.
Thanks - Gene
Hereâs the program the creates the serialized file.
using System;
using Microsoft.SPOT;
using System.Text;
using System.IO;
using Microsoft.SPOT.IO;
using GHI.IO.Storage;
namespace CreateMission
{
public class Program
{
[Serializable]
public struct DepthTable
{
public float depth;
public float PV;
public byte sampleList;
public TimeSpan parkTime;
}
[Serializable]
public class fullMission
{
public bool recoveryMode;
public TimeSpan samplePeriod;
public DepthTable[] descendTable;
public DepthTable[] ascendTable;
}
private static SDCard sdCard = new SDCard();
private static VolumeInfo sdVol;
public static void Main()
{
Debug.Print("Program Started");
sdCard.Mount();
sdVol = new VolumeInfo("SD");
Debug.Print("Create the full mission");
createMissionFile();
Debug.Print(" ");
Debug.Print("Load the mission file from disk");
loadMission();
}
private static StringBuilder fileName = new StringBuilder(128);
private static FileStream missionFile;
public static StringBuilder missionFileName = new StringBuilder(128);
public static void loadMission()
{
fileName.Clear();
fileName.Append(sdVol.RootDirectory);
fileName.Append("\\mission");
fileName.Append("60m");
fileName.Append(".mis");
missionFile = new FileStream(fileName.ToString(), FileMode.Open, FileAccess.Read);
byte[] fileBuffer = new byte[missionFile.Length];
missionFile.Read(fileBuffer, 0, (int)missionFile.Length);
fullMission missionFromFile = (fullMission)Reflection.Deserialize(fileBuffer, typeof(fullMission));
missionFile.Close();
}
private static void createMissionFile()
{
fullMission mission = new fullMission();
mission.recoveryMode = true;
mission.samplePeriod = new TimeSpan(0, 1, 0);
//First the descend table
mission.descendTable = new DepthTable[1];
mission.descendTable[0].depth = (float)60.0; //decimeters
mission.descendTable[0].PV = (float)0.10; //mm per second
mission.descendTable[0].parkTime = new TimeSpan(0, 10, 0);
mission.descendTable[0].sampleList = (byte)7;
//now cacluate the desired sample depths
float[] sampleDepth = genSampleDepths();
//fill out all the properties for each sampleDepth
int depthNum = sampleDepth.Length;
mission.ascendTable = new DepthTable[depthNum + 1];
for (int i = 0; i < depthNum; i++)
{
mission.ascendTable[i].depth = sampleDepth[i];
mission.ascendTable[i].PV = (float)0.10;
mission.ascendTable[i].sampleList = (byte)7;
mission.ascendTable[0].parkTime = new TimeSpan(0, 0, 0);
}
mission.ascendTable[depthNum].depth = (float)0.0;
mission.ascendTable[depthNum].PV = (float)0.10;
mission.ascendTable[depthNum].sampleList = (byte)0;
mission.ascendTable[0].parkTime = new TimeSpan(0, 0, 0);
//Serialize the mission
byte[] buffer = Reflection.Serialize(mission, typeof(fullMission));
//Check the serialization
fullMission checkMission = (fullMission)Reflection.Deserialize(buffer, typeof(fullMission));
//Debug.Print("Mission name = " + checkMission.missionName);
Debug.Print("Num of ascend table elements = " + checkMission.ascendTable.Length.ToString());
Debug.Print("Number of bytes in buffer = " + buffer.Length.ToString());
//Write the mission to SD Card
StringBuilder fileName = new StringBuilder(128);
fileName.Clear();
fileName.Append(sdVol.RootDirectory);
fileName.Append("\\mission");
fileName.Append("60m");
fileName.Append(".mis");
Debug.Print(fileName.ToString());
FileStream missionFileWriter = new FileStream(fileName.ToString(), FileMode.Create, FileAccess.Write);
missionFileWriter.Write(buffer, 0, buffer.Length);
missionFileWriter.Close();
//Read the mission back and check
FileStream missionFileReader = new FileStream(fileName.ToString(), FileMode.Open, FileAccess.Read);
byte[] fileBuffer = new byte[missionFileReader.Length];
missionFileReader.Read(fileBuffer, 0, (int)missionFileReader.Length);
//Deserialize here just to check
fullMission checkMissionOnFile = (fullMission)Reflection.Deserialize(fileBuffer, typeof(fullMission));
missionFileReader.Close();
}
private static float[] genSampleDepths()
{
int depthNum = 0;
float[] sampleDepth = new float[500];
float ascendDepth = (float)60.0;
while (ascendDepth > 0)
{
sampleDepth[depthNum] = ascendDepth;
depthNum = depthNum + 1;
if (ascendDepth > 20)
ascendDepth = ascendDepth - 5;
else
ascendDepth = ascendDepth - 2;
}
float[] returnArray = new float[depthNum];
Array.Copy(sampleDepth, returnArray, depthNum);
return (returnArray);
}
}
}
Hereâs the program that tries to read the serialized file
using System;
using Microsoft.SPOT;
using System.Text;
using System.IO;
using Microsoft.SPOT.IO;
using GHI.IO.Storage;
namespace loadMission
{
public class Program
{
[Serializable]
public struct DepthTable
{
public float depth;
public float PV;
public byte sampleList;
public TimeSpan parkTime;
}
[Serializable]
public class fullMission
{
public bool recoveryMode;
public TimeSpan samplePeriod;
public DepthTable[] descendTable;
public DepthTable[] ascendTable;
}
private static SDCard sdCard = new SDCard();
private static VolumeInfo sdVol;
public static void Main()
{
Debug.Print("Program Started");
sdCard.Mount();
sdVol = new VolumeInfo("SD");
Debug.Print("Loading the mission file");
loadMission();
}
private static StringBuilder fileName = new StringBuilder(128);
private static FileStream missionFile;
public static StringBuilder missionFileName = new StringBuilder(128);
public static void loadMission()
{
fileName.Clear();
fileName.Append(sdVol.RootDirectory);
fileName.Append("\\mission");
fileName.Append("60m");
fileName.Append(".mis");
missionFile = new FileStream(fileName.ToString(), FileMode.Open, FileAccess.Read);
byte[] fileBuffer = new byte[missionFile.Length];
missionFile.Read(fileBuffer, 0, (int)missionFile.Length);
fullMission missionFromFile = (fullMission)Reflection.Deserialize(fileBuffer, typeof(fullMission));
missionFile.Close();
}
}
}
Hereâs the exception
#### Exception Microsoft.SPOT.UnknownTypeException - CLR_E_UNKNOWN_TYPE (1) ####
#### Message:
#### Microsoft.SPOT.Reflection::Deserialize [IP: 0000] ####
#### loadMission.Program::loadMission [IP: 0068] ####
#### loadMission.Program::Main [IP: 0022] ####
A first chance exception of type âMicrosoft.SPOT.UnknownTypeExceptionâ occurred in Microsoft.SPOT.Native.dll
An unhandled exception of type âMicrosoft.SPOT.UnknownTypeExceptionâ occurred in Microsoft.SPOT.Native.dll