Скопировать данные из IntPtr в IntPtr
У меня есть два значения IntPtr
, указывающие на некоторые области данных length
байт. length
может иметь порядок от 200 к 400 к.
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);
но у него есть недостаток необходимости в дополнительном временном (потенциально огромном) массиве. К сожалению, я не смог найти вариант Marshal.Copy
в платформе .NET для копирования непосредственно из IntPtr
в IntPtr
, поэтому я ищу альтернативы.
Меня интересует решение, которое работает на 32 Windows, а также на 64-битной Windows. Любые предложения?
Ответы
Ответ 1
Вы можете 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);
}
}
Ответ 2
Я думаю, что ответ нуждается в обновлении в .net 4.6, там есть
Buffer.MemoryCopy Method (Void*, Void*, Int64, Int64)
Этот метод копирует байты sourceBytesToCopy с адреса, указанного источником, на адрес, указанный адресатом. Если буферы перекрываются, а разница между целевым минусом источника меньше, чем sourceBytesToCopy, исходный блок копируется в целевой блок в обратном порядке.
Итак, если вы не используете 4.6 или универсальное приложение Windows 10, используйте предыдущий ответ.
Ответ 3
Как указывает пользователь 38000527, современный ответ - MemoryCopy, и он является частью .NET core 1.0,.NET standard 1.3 и .NET framework 4.6.
Вот как вы используете это в вашем контексте:
Buffer.MemoryCopy(ptrSrc.ToPointer(), ptrDest.ToPointer(), length, length)