Подтвердить что ты не робот

Скопировать данные из 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. Любые предложения?

4b9b3361

Ответ 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)