Как преобразовать фиксированный байт / символ [100] в управляемый символ [] в C#?
Каков наилучший способ преобразования фиксированного байта или символа [100] в управляемый символ [] в C#? Мне пришлось использовать арифметику с указателями, и мне интересно, есть ли более простой способ - что-то вроде memcpy или другого способа?
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);
}
}
}
2 ответа
Вы можете использовать Marshal.Copy для этого. Обратите внимание, что он также перегружен для байта [], который может быть более подходящим типом данных.
Я не знаю лучшего способа сделать преобразование с фиксированной переменной. Однако один из способов сделать это проще - полностью избежать использования фиксированной переменной. Вместо этого используйте обычный массив 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(); }
}
}