What's the best way to convert a fixed byte or char[100] to a managed char[] in C#? I ended up having to use pointer arithmetic and I'm wondering if there is an easier way -- something like a memcpy or another way?
在C#中将固定字节或char [100]转换为托管char []的最佳方法是什么?我最终不得不使用指针算法,我想知道是否有更简单的方法 - 像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 个解决方案
#1
You can use Marshal.Copy for that. Notice it is also overloaded for byte[], which might be a more appropriate data type.
你可以使用Marshal.Copy。请注意,byte []也会重载,这可能是更合适的数据类型。
#2
I don't know of a better way to do the conversion on a fixed variable. However one way to make this simpler is to avoid the use of a fixed variable altogether. Instead use a normal C# array and mark it as a UnmanagedType.ByValArray
我不知道在固定变量上进行转换的更好方法。然而,使这更简单的一种方法是完全避免使用固定变量。而是使用普通的C#数组并将其标记为UnmanagedType.ByValArray
[FieldOffset(0), MarshalAs(UnmanagedType.ByValArray, SizeConst = BUFFER_SIZE)]
private byte[] writeBuffer;
Then you can use a simple LINQ query to translate the data. Full solution below
然后,您可以使用简单的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
You can use Marshal.Copy for that. Notice it is also overloaded for byte[], which might be a more appropriate data type.
你可以使用Marshal.Copy。请注意,byte []也会重载,这可能是更合适的数据类型。
#2
I don't know of a better way to do the conversion on a fixed variable. However one way to make this simpler is to avoid the use of a fixed variable altogether. Instead use a normal C# array and mark it as a UnmanagedType.ByValArray
我不知道在固定变量上进行转换的更好方法。然而,使这更简单的一种方法是完全避免使用固定变量。而是使用普通的C#数组并将其标记为UnmanagedType.ByValArray
[FieldOffset(0), MarshalAs(UnmanagedType.ByValArray, SizeConst = BUFFER_SIZE)]
private byte[] writeBuffer;
Then you can use a simple LINQ query to translate the data. Full solution below
然后,您可以使用简单的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(); }
}
}