c# - 有没有一种可移植的方法可以在 C# 中复制一 block 内存?

标签 c# arrays pointers copy memcpy

如果您想在两个数组之间进行内存复制,.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:要求srcdst为数组
  • 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/

相关文章:

c# - 如何忽略必填字段验证中的第一个索引

c# - 在 C# WPF 中恢复下载

c# - 在类库项目中统一依赖注入(inject)

c++ - leetcode 540上的运行时错误。已排序数组中的单个元素

带指针的 C 输出

c# - 有没有办法将 C# 中的 IntPtr/void* 转换为 ref SomeStruct?

c# - 在 C# 中使用 AForge.Video.FFMEG 向图像添加文本

javascript - 为什么会这样? (JavaScript 的反向方法)

Python Numpy 将旋转矩阵应用于数组中的每一行

char * 变量地址 vs. char [] 变量地址