我有两个非托管指针,IntPtr并希望在它们之间复制数据.我怎样才能做到这一点?我知道这个方法Marshal.Copy,但它只能在非托管和托管之间进行复制.第二部分:使用memcpy从C#中复制非托管数据比在非托管C/C++中复制更慢吗?
编辑:我会对平台独立实现特别感兴趣.
Ash*_*Ash 16
您可以通过P-Invoke 使用win32 memcpy函数.
[DllImport("msvcrt.dll", SetLastError = false)]
static extern IntPtr memcpy(IntPtr dest, IntPtr src, int count);
Run Code Online (Sandbox Code Playgroud)
除了从托管代码调用win32函数的(轻微)开销之外,实际的复制性能应该与使用相同函数的C/C++代码相同.
不要忘记您也可以使用不安全的块(和编译器选项),并且一次只能复制一个字节/ int/long的数据:
unsafe
{
// srcPtr and destPtr are IntPtr's pointing to valid memory locations
// size is the number of long (normally 4 bytes) to copy
long* src = (long*)srcPtr;
long* dest = (long*)destPtr;
for (int i = 0; i < size / sizeof(long); i++)
{
dest[i] = src[i];
}
}
Run Code Online (Sandbox Code Playgroud)
这将删除平台依赖关系,但您需要非常小心边界检查和指针算法.
如果可以使用.NET 4.6或更高版本,请尝试使用System.Buffer.MemoryCopy.我相信这个和使用P/Invoke的其他解决方案之间的主要区别在于,这种方法避免了较小尺寸的P/Invoke,只是直接进行复制.
以下是 .NET Core中实现的内容(最新版本为2018-06-19).
没有对性能发表评论,纯粹是因为我没有测试过它.通过使用来自Kernel32的CopyMemory或MoveMemory,可以通过interop实现与非托管副本相同的性能.
这是CopyMemory的声明
[DllImport("kernel32.dll")]
static extern void CopyMemory(IntPtr destination, IntPtr source, uint length);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15493 次 |
| 最近记录: |