2009-06-29 15 views
3

私はSilverlightでMiscUtil.Conversionユーティリティを使用しようとしています。私はそれをコンパイルしようとすると http://www.yoda.arachsys.com/csharp/miscutil/SilverlightのBigEndianBitConverter?

が、私はSilverlightののBitConverterクラスは、これらの2つの方法がないというエラーが出ます:

DoubleToInt64Bits Int64BitsToDouble

まあが、私はリフレクターを開いて、mscorlibでそれらを発見しました:

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

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

しかし、問題は、Silverlightでは安全でないコードが許可されないということです。プロジェクトのプロパティメニューには、「安全でないコードを許可する」の横に空のチェックボックスがありますが、値を変更することはできません。

Silverlightでこれを行うにはどうすればよいですか?

答えて

3

BitConverter.ToDouble(byte[], int)BitConverter.GetBytes(double)をご覧ください。それらがSilverlightに存在する場合、十分に良いかもしれません。とにかくプロトコルバッファのためにこれを調べるつもりです。もし私が良い解決策を見つけたら、私はそれをMiscUtilに移植します。

+0

ああ、そうです。私のPCはBitConverter.IsLittleEndianをtrueにしていますが、Mac上でfalseになるのだろうかと思います。 私はチェックを追加します: if(BitConverter.IsBigEndian) bytes = bytes.Reverse()。ToArray(); –

+0

Reflectorによると、これらのメソッドはデスクトップマシン上では安全ではないとマークされています。彼らはSilverlightでそれらを通常の方法にすることができましたか? –

+0

私は、実装上安全ではないかもしれないが、MSがSilverlight用にそれらを利用できるように十分信頼できると思う。結局のところ、あなたがファイルシステムやグラフィックスなどを呼び出すつもりなら、遅かれ早かれ安全でないコードを打つことになります。これらのことを知ってうれしい* do * Silverlight上に存在する... –

0

これはSilverlightで動作するかどうかわかりませんが、コンソールアプリケーションでは機能し、安全でないコードは必要ありません。

バイト配列に二重の値を取得できる場合は、バイト配列内のバイトをスワップしてエンディアンを変更できます。バイト配列を二重に戻して、プロセスを逆にすることもできます。

次のコードは、System.InteropServicesを使用して、ダブル配列とバイト配列を変換する方法を示しています。 Mainメソッドは、コンソールに2つの値、8と3.14159を返します。 8は、8バイトのバイト配列がdoubleから正常に作成されたことを示し、3.14159は、doubleがバイト配列から正しく抽出されたことを示します。

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

クールなアイデア。しかし、FreeHGlobalとAllocHGlobalは、Silverlightの保護レベルのためにアクセスできません。 IntPtr buffer = new IntPtr(0)を実行しようとしましたが、割り当てられていないという不満がありました。 IntPtrを割り当てることができない場合、なぜそれらを使用するのですか? –

関連する問題