12

I'm using this code to save bytes from a IntPtr buffer in unmanaged code to file. It's a simple callback function:

private void callback(IntPtr buffer, int length)
{
    byte[] bytes = new byte[length];
    Marshal.Copy(buffer, bytes, 0, length);
    FileStream file = new FileStream(filename, FileMode.Create, FileAccess.Write);
    file.Write(bytes, 0, length);
    file.Close();
}

What I want is to store this data to file and throw it away. From what I understand there is a buffer in the unmanaged code and a 2nd one in MY code. I don't want to copy the data around I want it directly:

// bad:     (unmanaged) buffer -> (managed) bytes -> file
// awesome: (unmanaged) buffer ->                    file

For my task I need the most quickest way to store the data to file.

Bitterblue
  • 13,162
  • 17
  • 86
  • 124

2 Answers2

18

Staying within the .NET framework is probably better form than using calls to kernel dlls.

I would use:

private void callback(IntPtr buffer, int length, String filename)
{
    try
    {
        FileStream file = new FileStream(filename, FileMode.Create, FileAccess.Write);
        UnmanagedMemoryStream ustream = new UnmanagedMemoryStream((byte*)buffer, length);
        ustream.CopyTo(file);
        ustream.Close();
        file.Close();
    }
    catch{/** To do: catch code **/}
}
bluish
  • 26,356
  • 27
  • 122
  • 180
user2163234
  • 527
  • 5
  • 9
6

Well, it's called "managed" for some reason :-) What you can do though is declare WriteFile using P/Invoke, like this:

private void callback(IntPtr buffer, int length)
{
    FileStream file = new FileStream(filename, FileMode.Create, FileAccess.Write);
    int written;
    WriteFile(file.Handle, buffer, length, out written, IntPtr.Zero);
    file.Close();
}

 [DllImport("kernel32.dll")]
 private static extern bool WriteFile(IntPtr hFile, IntPtr lpBuffer, int NumberOfBytesToWrite, out int lpNumberOfBytesWritten, IntPtr lpOverlapped);
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298