36

我有两个IntPtr值指向一些length字节数据区域。length可能有 200k 到 400k 的数量级。

int length = /* ..*/
IntPtr ptrSrc = /*.. */;
IntPtr ptrDst = /* .. */;

现在我想将数据从 复制ptrSrcptrDst. 此代码工作正常:

byte[] data = new byte[length];
Marshal.Copy(ptrSrc, data, 0, length);
Marshal.Copy(data, 0, ptrDst, length);

但它的缺点是需要一个额外的临时(可能是巨大的)数组。Marshal.Copy不幸的是,我在 .NET 框架中找不到用于直接从IntPtrto复制的变体IntPtr,因此我正在寻找替代方案。

我对适用于 32 位 Windows 和 64 位 Windows 的解决方案感兴趣。有什么建议么?

4

3 回答 3

45

您可以 P/Invoke 到适当的 C 函数中。这可能是最简单的方法。例子:

class Program
{
    [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
    public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);

    static void Main()
    {
        const int size = 200;
        IntPtr memorySource = Marshal.AllocHGlobal(size);
        IntPtr memoryTarget = Marshal.AllocHGlobal(size);

        CopyMemory(memoryTarget,memorySource,size);
    }
}
于 2013-04-12T16:09:59.807 回答
22

我认为答案需要在 .net 4.6 中进行更新

 Buffer.MemoryCopy Method (Void*, Void*, Int64, Int64)

此方法将 sourceBytesToCopy 字节从 source 指定的地址复制到 destination 指定的地址。如果缓冲区重叠并且目标减去源之间的差异小于 sourceBytesToCopy,则源块以相反的顺序复制到目标块。

因此,如果您不在 4.6 或通用 Windows 应用程序 10 上,请使用上一个答案。

于 2017-08-04T07:25:11.093 回答
9

正如user38000527 指出的那样,现代答案是MemoryCopy,它是 .NET core 1.0、.NET standard 1.3 和 .NET framework 4.6 的一部分。

以下是您在上下文中使用它的方式:

Buffer.MemoryCopy(ptrSrc.ToPointer(), ptrDest.ToPointer(), length, length) 
于 2019-01-13T20:31:27.760 回答