2009-07-26 14 views
2

Was ist der beste Weg, um ein festes Byte oder char [100] in ein verwaltetes char [] in C# zu konvertieren? Ich musste am Ende Zeigerarithmetik verwenden und ich frage mich, ob es einen einfacheren Weg gibt - etwas wie eine Memcpy oder eine andere Möglichkeit?Wie konvertiert man in C# fixed byte/char [100] in managed 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); 
     } 
    } 
} 

Antwort

3

Sie können Marshal.Copy dafür verwenden. Beachten Sie, dass es auch für Byte [] überladen ist, was möglicherweise ein geeigneterer Datentyp ist.

+0

ich die Write Eigenschaft aktualisiert ein Byte zurück [] und dann verwendet Marshal.Copy. Es sollte wahrscheinlich Byte [] an erster Stelle gewesen sein. –

0

Ich kenne keine bessere Möglichkeit, die Konvertierung auf einer festen Variablen zu tun. Eine Möglichkeit, dies zu vereinfachen, besteht jedoch darin, die Verwendung einer festen Variablen insgesamt zu vermeiden. Verwenden Sie stattdessen einen normalen # Array C und markieren Sie es als UnmanagedType.ByValArray

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

Dann können Sie eine einfache LINQ-Abfrage verwenden, um die Daten zu übersetzen. Vollständige Lösung unter

[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

Ich hatte versucht, ein UnmanagedType.ByValArray auf writeBuffer, aber ich bekam Laufzeit Ausnahmen wie unten. Würde diese Ausnahme nicht auch für Ihr Beispiel auftreten? Wenn nicht, könnten Sie mir erklären warum? Nicht behandelte Ausnahme: System.TypeLoadException: Konnte den Typ 'StructTest.OuterType' nicht aus Assembly 'StructTest, Version = 1.0.0.0, Culture = Neutral, PublicKeyToken = null' laden, weil es ein Objektfeld bei falschem Offset 0 enthält ausgerichtet oder überlappt von einem Nicht-Objekt-Feld. bei StructTest.Program.Main (String [] args) –

+0

Die Einschränkung, die ich habe, ist, dass ich meine Struktur eine Union sein muss, weshalb ich FieldOffset (0) für jeden benötigen. –

+0

Ich habe das versucht und ich bekomme die Ausnahme, die ich früher kommentiert habe, wenn beide FieldOffset (0) haben. –

Verwandte Themen