如果您想在两个数组之间进行内存复制,.NET 中有一个 Array.Copy
函数:
char[] GetCopy(char[] buf)
{
char[] result = new char[buf.Length];
Array.Copy(buf, result);
return result;
}
这通常比手动将 buf
中的所有字符复制到 result
中的 for 循环更快,因为它是一个 block 复制操作,只占用一 block 内存并且将其写入目的地。
同样,如果给我一个 char*
和一个指定其大小的 int
,我有什么选择?以下是我考虑过的:
- Buffer.BlockCopy:要求
src
和dst
为数组 - Buffer.MemoryCopy:正是我要找的,但仅在 .NET 桌面上可用
- Marshal.Copy:.NET 2.0 不再支持
或者,如果别无选择,是否有某种方法可以从指针 char*
和长度 int
构造数组?如果我能做到这一点,我可以将指针转换为数组并将它们传递给 Array.Copy。
我不是在寻找 for 循环,因为正如我所说,与 block 副本相比,它们不是很有效,但如果这是唯一的方法,我想那是必须要做的。
TL;DR:我基本上是在寻找 memcpy()
,但在 C# 中并且可以在 PCL 中使用。
最佳答案
您声明 Marshal.Copy
将不再受支持,但是在 Marshal 的文档中类我找不到任何迹象。
恰恰相反,该类适用于以下框架版本:4.6、4.5、4、3.5、3.0、2.0、1.1
基于此方法的效用函数的一种可能实现方式是:
public static void CopyFromPtrToPtr(IntPtr src, uint srcLen,
IntPtr dst, uint dstLen)
{
var buffer = new byte[srcLen];
Marshal.Copy(src, buffer, 0, buffer.Length);
Marshal.Copy(buffer, 0, dst, (int)Math.Min(buffer.Length, dstLen));
}
但是,很有可能将字节从 IntPtr
复制到 byte[]
并再次复制回来抵消固定不安全内存并复制它的任何可能的性能提升在一个循环中。
根据代码需要的可移植性,您还可以考虑使用 P/Invoke 来实际使用 memcpy
方法。这应该适用于 Windows 2000 及更高版本(所有安装了 Microsoft Visual C 运行时库的系统)。
[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
static extern IntPtr memcpy(IntPtr dst, IntPtr src, UIntPtr count);
编辑:第二种方法不适合可移植类库,但第一种方法适合。
关于c# - 有没有一种可移植的方法可以在 C# 中复制一 block 内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31932170/