我们如何复制Marshal.AllocHGlobal分配的两个缓冲区?

时间:2016-02-03 10:59:00

标签: c# pinvoke unsafe

Marshal中有一些方法可以将AllocHGlobal分配的原始缓冲区复制到C#数组中。但我的问题是,我有两个缓冲区都由AllocHGlobal分配,我想简单地将一个缓冲区复制到另一个缓冲区。

var buffer1 = Marshal.AllocHGlobal(size);
var buffer2 = Marshal.AllocHGlobal(size);
nativeOpOn(buffer1);
SomeCopy(buffer1, buffer2, size);

我知道一个可能的解决方案是针对memcpy的P / Invoke系统C lib,但是我必须编写不同的P / Invoke以支持Windows和Linux以及MacOS,因为它们可能有不同的P / Invoke东西。

2 个答案:

答案 0 :(得分:4)

如果您使用的是.Net 4.6或更高版本,则可以使用Buffer.MemoryCopy()

unsafe
{
    Buffer.MemoryCopy(p1.ToPointer(), p2.ToPointer(), destSizeBytes, sourceBytesToCopy);
}

当然,它是unsafe

答案 1 :(得分:1)

您可以使用以下方法:

1)托管缓冲区:

int size = sizeof(int); // for test purposes
IntPtr buffer1 = Marshal.AllocHGlobal(size);
IntPtr buffer2 = Marshal.AllocHGlobal(size);

Marshal.WriteInt32(buffer1, 0x12345678); // native op (for test purposes)

byte[] bytes = new byte[size]; // managed buffer
Marshal.Copy(buffer1, bytes, 0, size); //buffer1=>bytes
Marshal.Copy(bytes, 0, buffer2, size); //bytes=>buffer2
// use several iterations if needed

int res =  Marshal.ReadInt32(buffer2, 0); // for test purposes (res==0x12345678)

2)通过Marshal.ReadByte/WriteByte方法或任何Marshal.ReadXXXe/WriteXXX方法(取决于size)管理读/写操作。只需在循环中重复这些操作:

for(int i = 0; i < size; i++) 
    Marshal.WriteByte(buffer2, i, Marshal.ReadByte(buffer1, i));

3)不安全的块(通过不安全的指针读/写缓冲区)