2009-07-26 20 views
2

C#で固定バイトまたはchar [100]をマネージchar []に変換する最良の方法は何ですか?私はポインタの算術演算を使用する必要があったため、より簡単な方法があるかどうか疑問に思っています - memcpyまたは別の方法のようなもの?C#で固定バイト/ char [100]をマネージchar []に変換する方法は?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 

namespace StructTest 
{ 

    [StructLayout(LayoutKind.Explicit)] 
    unsafe struct OuterType 
    { 
     private const int BUFFER_SIZE = 100; 

     [FieldOffset(0)] 
     private int transactionType; 

     [FieldOffset(0)] 
     private fixed byte writeBuffer[BUFFER_SIZE]; 

     public int TransactionType 
     { 
      get { return transactionType; } 
      set { transactionType = value; } 
     } 

     public char[] WriteBuffer 
     { 
      set 
      { 
       char[] newBuffer = value; 

       fixed (byte* b = writeBuffer) 
       { 
        byte* bptr = b; 
        for (int i = 0; i < newBuffer.Length; i++) 
        { 
         *bptr++ = (byte) newBuffer[i]; 
        } 
       } 
      } 

      get 
      { 
       char[] newBuffer = new char[BUFFER_SIZE]; 

       fixed (byte* b = writeBuffer) 
       { 
        byte* bptr = b; 
        for (int i = 0; i < newBuffer.Length; i++) 
        { 
         newBuffer[i] = (char) *bptr++; 
        } 
       } 

       return newBuffer; 
      } 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      OuterType t = new OuterType(); 
      t.WriteBuffer = "hello there".ToCharArray(); 
      System.Console.WriteLine(t.WriteBuffer); 
     } 
    } 
} 

答えて

3

これにはMarshal.Copyを使用できます。より適切なデータ型かもしれないbyte []に​​対してもオーバーロードされていることに注意してください。

+0

WriteBufferプロパティを更新してバイト[]を返し、Marshal.Copyを使用しました。最初はバイト[]だったはずです。 –

0

私は、固定変数の変換を行うためのより良い方法がわかりません。しかし、これを簡単にする方法の1つは、固定変数の使用を避けることです。代わりに、そして、あなたがデータを変換するために、単純なLINQクエリを使用することができますUnmanagedType.ByValArray

[FieldOffset(0), MarshalAs(UnmanagedType.ByValArray, SizeConst = BUFFER_SIZE)] 
private byte[] writeBuffer; 

として、通常のC#の配列を使用し、それをマーク。以下の完全なソリューション

[StructLayout(LayoutKind.Explicit)] 
unsafe struct OuterType 
{ 
    private const int BUFFER_SIZE = 100; 

    [FieldOffset(0)] 
    private int transactionType; 

    [FieldOffset(0), MarshalAs(UnmanagedType.ByValArray, SizeConst = BUFFER_SIZE)] 
    private byte[] writeBuffer; 

    public int TransactionType 
    { 
     get { return transactionType; } 
     set { transactionType = value; } 
    } 

    public char[] WriteBuffer 
    { 
     set { writeBuffer = value.Cast<byte>().ToArray(); } 
     get { return writeBuffer.Cast<char>().ToArray(); } 
    } 
} 
+1

私はwriteBufferでUnmanagedType.ByValArrayを試しましたが、以下のような実行時例外が発生しました。その例外はあなたの例でも起こりませんか?もしそうでなければ、あなたはなぜ私を教えてくれますか? ハンドルされていない例外:System.TypeLoadException:アセンブリ 'StructTest、Version = 1.0.0.0、Culture = neutral、 PublicKeyToken = null'から 'StructTest.OuterType'型をロードできませんでした。アライメントされていないか、または非オブジェクトフィールドによってオーバーラップされています。 StructTest.Program.Main(String [] args) –

+0

私の制限は、私が構造体を必要としているため、それぞれにFieldOffset(0)が必要なためです。 –

+0

私はこれを試して、彼らは両方ともFieldOffset(0)を持っている場合、私は以前コメントした例外を取得しています。 –