[Mono-list] Re: Remoting compatibility between MS.NET and Mono
Robert Jordan
robertj@gmx.net
Tue, 01 Mar 2005 22:41:46 +0100
Hi Sébastien,
> I know for instance that basic types are compatibles between both platforms (array, string, int, etc.). Some classes (such as Guid)
> are also remotable, while other structs/classes such as CultureInfo and BitArray are not. Classes that share the same implementation
> on both sides are usually remotable (I never had problem with my own classes/structs).
Binary serialization depends on the *names* of the fields.
For example Mono uses for BitArray's implementation these
field names:
System.Collections.BitArray._array
System.Collections.BitArray._length
System.Collections.BitArray._version
while MSFT uses:
System.Collections.BitArray.m_array
System.Collections.BitArray.m_length
System.Collections.BitArray._version
It's quite hard for a Mono developer which is expected *not*
to cheat on MSFT's code to choose the same private field names.
It's even harder when a class is implementing ISerializable.
In this case the developer must cheat.
> On the other end, if there was a list of the compatible types available (on the mono web site for example), this could really help
> people like me to avoid using types that are not compatible (just a suggestion :-)
You may help yourself using the following code on both
platforms and diffing the output.
usage: mono sdump.exe PartialAssemblyName [TypeName]
samples:
mono sdump.exe mscorlib
mono sdump.exe mscorlib System.Collections.BitArray
bye
Rob
-- cut-here --
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Serialization;
public class SDumpApp
{
[STAThread]
static void Main(string[] args)
{
if (args == null || args.Length < 1)
{
Console.Error.WriteLine("usage: sdump PartialAssemblyName
[TypeName]");
Environment.Exit(1);
}
try
{
Assembly asm = Load(args[0]);
if (args.Length > 1)
{
Process(asm.GetType(args[1], true));
}
else
{
Process(asm);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static Assembly Load(string name)
{
Assembly asm = Assembly.LoadWithPartialName(name);
if (asm == null)
{
throw new TypeLoadException(String.Format("Assembly '{0}'
not found.", name));
}
else
{
return asm;
}
}
static bool IsTypeApplicable(Type t)
{
if (t.IsSerializable &&
!typeof(ISerializable).IsAssignableFrom(t))
return true;
else
return false;
}
static void Process(Assembly asm)
{
Type[] types = asm.GetExportedTypes();
int count = 0;
foreach (Type t in types)
{
if (IsTypeApplicable(t))
{
Process(t);
count++;
}
}
Console.WriteLine("#{0}", count);
}
static void Process(Type t)
{
foreach (MemberInfo mi in
FormatterServices.GetSerializableMembers(t))
{
Console.WriteLine("{0}.{1}", t.FullName, mi.Name);
}
}
}