2009-06-29 5 views
3

J'essaie d'utiliser l'utilitaire MiscUtil.Conversion dans Silverlight. http://www.yoda.arachsys.com/csharp/miscutil/BigEndianBitConverter dans Silverlight?

Lorsque je tente de le compiler, je reçois une erreur disant que la classe BitConverter de Silverlight n'a pas ces deux méthodes:

DoubleToInt64Bits Int64BitsToDouble

Eh bien, j'ai ouvert réflecteur et les ai trouvés dans mscorlib :

public unsafe long DoubleToInt64Bits(double value) 
{ 
    return *(((long*)&value)); 
} 

public unsafe double Int64BitsToDouble(long value) 
{ 
    return *(((double*) &value)); 
} 

Mais le problème avec cela est que Silverlight ne permet pas le code dangereux. Dans le menu des propriétés du projet, il y a une case à cocher vide à côté de "autoriser le code non sécurisé", mais vous ne pouvez pas changer la valeur.

Comment puis-je faire cela dans Silverlight?

Répondre

3

Jetez un oeil à BitConverter.ToDouble(byte[], int) et BitConverter.GetBytes(double). Si elles existent dans Silverlight, elles peuvent être assez bonnes. Je vais quand même étudier cela pour les tampons de protocole - si je trouve une bonne solution, je vais la reporter sur MiscUtil.

+0

Oh, ouais c'est vrai. Mon PC a BitConverter.IsLittleEndian comme vrai, mais je me demande si ce serait faux sur un Mac. Je vais ajouter une vérification: if (BitConverter.IsBigEndian) octets = bytes.Reverse(). ToArray(); –

+0

Ces méthodes sont marquées comme dangereuses sur mon ordinateur de bureau, selon Reflector. Ont-ils réussi à en faire des méthodes ordinaires dans Silverlight? –

+0

Je suppose qu'ils peuvent être dangereux sur le plan de la mise en œuvre, mais suffisamment fiables de la part de MS pour les rendre disponibles pour Silverlight. Après tout, si vous appelez le système de fichiers, les graphiques ou autre chose, tôt ou tard, vous avez * obtenu * de frapper un code dangereux. Heureux de savoir que ces * do * existent sur Silverlight si ... –

0

Je ne sais pas si cela fonctionnera dans Silverlight ou non, mais cela fonctionne dans une application de la console, et il ne nécessite pas de code dangereux.

Si vous pouvez obtenir vos valeurs doubles dans un tableau d'octets, vous pouvez échanger les octets dans le tableau d'octets pour changer l'endian-ness. Le processus peut également être inversé, en changeant le tableau d'octets en double.

Le code suivant illustre la conversion entre un tableau double et un tableau d'octets, à l'aide de System.InteropServices. La méthode Main renvoie deux valeurs dans la console: 8 et 3.14159. Le 8 indique qu'un tableau d'octets de 8 octets a été créé avec succès à partir du double, et 3.14159 indique que le double a été correctement extrait du tableau d'octets.

using System; 
using System.IO; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      double d = 3.14159d; 
      byte[] b = ToByteArray(d); 
      Console.WriteLine(b.Length); 
      Console.ReadLine(); 
      double n = FrpmByteArray(b); 
      Console.WriteLine(n.ToString()); 
      Console.ReadLine(); 
     } 
     public static byte[] ToByteArray(object anything) 
     { 
      int structsize = Marshal.SizeOf(anything); 
      IntPtr buffer = Marshal.AllocHGlobal(structsize); 
      Marshal.StructureToPtr(anything, buffer, false); 
      byte[] streamdatas = new byte[structsize]; 
      Marshal.Copy(buffer, streamdatas, 0, structsize); 
      Marshal.FreeHGlobal(buffer); 
      return streamdatas; 
     } 
     public static double FromByteArray(byte[] b) 
     { 
      GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned); 
      double d = (double)Marshal.PtrToStructure(
       handle.AddrOfPinnedObject(), 
       typeof(double)); 
      handle.Free(); 
      return d; 
     } 

    } 
} 
+0

Cool idée. Mais FreeHGlobal et AllocHGlobal sont inaccessibles en raison de leur niveau de protection dans Silverlight. J'ai essayé de faire IntPtr buffer = new IntPtr (0), mais ensuite il s'est plaint de ne pas être alloué. Pourquoi voudraient-ils nous laisser utiliser IntPtr si nous ne pouvons pas les allouer? –