将数据从IntPtr复制到IntPtr

时间:2013-04-12 16:02:35

标签: c#

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

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

现在我想将数据从ptrSrc复制到ptrDst。这段代码工作正常:

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

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

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

3 个答案:

答案 0 :(得分:38)

你可以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);
    }
}

答案 1 :(得分:10)

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

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

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

因此,如果您没有使用4.6或通用Windows应用10,请使用之前的答案。

答案 2 :(得分:1)

user38000527 points out一样,现代的答案是MemoryCopy,它是.NET Core 1.0,.NET Standard 1.3和.NET Framework 4.6的一部分。

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

Buffer.MemoryCopy(ptrSrc.ToPointer(), ptrDest.ToPointer(), length, length)