How can I in C # stream.Read into an unmanaged memory stream?

I can read unmanaged memory in C # using UnmanagedMemoryStream, but how can I do the opposite?

I want to read from a managed stream directly to unmanaged memory instead of first reading in byte [], and then copying. I am doing an asynchronous stream reading over a large number of requests, so the added memory is significant (not to mention an extra copy).

+3
source share
3 answers

I think this is really impossible. When you talk about controlled flow, I suppose you are referring to an instance of System.IO.Stream or a subclass.

[] , .

, , , [], * , * , :

unsafe function test()
{
    var buffer = new byte[1024];
    fixed (byte* bufferPtr = &buffer[0])
    {   
        // Read bytes and pass the ptr to a function that needs to
        // operate on data directly 
    }
}

,

. . - . , GC . "" , , .

+2

, , , . , UnmanagedMemoryStream - .

, , . UnmanagedMemoryStream . ! . ++/CLI :

void CopyStreamToNativePtr(Stream^ src, unsigned char* dst)
{
    // Assuming we want to start the copy at the beginning of src
    src->Seek(0, SeekOrigin::Begin);

    // Create an UnmanagedMemoryStream on top of the destination
    // with an appropriate size and capacity (We assume the buffer is
    // is sized to the source data in this function!)
    UnmanagedMemoryStream target(dst, src->Length, src->Length, FileAccess::Write);

    // Copy to your heart content!
    src->CopyTo(%target);

    // We made the UnmanagedMemoryStream local so that we wouldn't have
    // to explicitly Dispose() of it.
}
+4

The managed thread will always have a reference to the "managed" object for the actual byte [] object. However, you can use a managed byte[]one that is tied to an unmanaged memory allocation and, therefore, makes it available as an unmanaged memory block:

byte[] data = new byte[];
GCHandle pin = GCHandle.Alloc(data, GCHandleType.Pinned)
try {
  IntPtr dataUnmanagedPtr = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0);
  // managed.Read(data, index, count);
  // use the unmanaged pointer here for unmanaged code
} finally {
  pin.Free(pin); // but make sure that no unmanaged code uses the pinned data anymore upon release
}
+1
source

Source: https://habr.com/ru/post/1716677/


All Articles