2009-07-26 26 views
2

Каков наилучший способ преобразования фиксированного байта или char [100] в управляемый символ char [] в C#? Мне пришлось использовать арифметику указателей, и мне интересно, есть ли более простой способ - что-то вроде memcpy или по-другому?Как преобразовать фиксированный байт/char [100] в управляемый символ char [] в C#?

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. Обратите внимание, что он также перегружен для байта [], который может быть более подходящим типом данных.

+0

Я обновил свойство WriteBuffer, чтобы вернуть байт [], а затем использовал Marshal.Copy. Вероятно, это должен был быть байт []. –

0

Я не знаю, как лучше преобразовать фиксированную переменную. Однако один из способов сделать это проще - вообще избегать использования фиксированной переменной. Вместо того, чтобы использовать обычный C# массив и пометить его как UnmanagedType.ByValArray

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

Затем вы можете использовать простой запрос LINQ для преобразования данных. Полное решение ниже

[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

Я пробовал UnmanagedType.ByValArray на writeBuffer, но я получал исключения во время выполнения, как показано ниже. Разве это исключение не возникнет и для вашего примера? Если нет, не могли бы вы рассказать мне почему? Unhandled Exception: System.TypeLoadException: Не удалось загрузить тип 'StructTest.OuterType' из сборки 'StructTest, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null', потому что он содержит поле объекта со смещением 0, которое неверно выравнивается или перекрывается полем, отличным от объекта. at StructTest.Program.Main (String [] args) –

+0

Ограничение, которое у меня есть, это то, что мне нужно, чтобы моя структура была объединением, поэтому мне нужен FieldOffset (0) для каждого. –

+0

Я пробовал это, и я получаю исключение, о котором я прокомментировал ранее, если оба они имеют FieldOffset (0). –

Смежные вопросы