4

I am using a camera SDK from the manufacturer, and they are giving me a class called Image with a pointer called data of type byte* that points to the beginning of the image data. They also give me a uint called dataSize that corresponds to the length of data.

Now, I want to write this into a file using FileStream, but unfortunately the only write function in FileStream is of signature Write(Byte[], Int32, Int32). Naturally, if I try to use data as a parameter to Write(...), it tells me I cannot convert from byte* to byte[].

Since in my application, performance is critical, I want to avoid copying the data into a byte[] array using Marshal.Copy(...) as suggested in this answer.

What other options do I have available to me to take this byte* pointer and write it to a file? Note that my overall goal is to take these images, which are coming in thousands per second, and write them to disk as fast as possible (i.e. sequentially for an SSD).

Community
  • 1
  • 1
ArKi
  • 681
  • 1
  • 10
  • 22
  • I think the issue is you cant convert unmanaged memory to managed memory without going through the process of copying to a new managed block. If memory use is a concern can you write to file using a buffer so you can limit the extra memory usage to the size of the buffer? – meganaut Dec 02 '16 at 03:30
  • I'm worried about the performance hit of copying the data to the managed block before writing it out. That seems awfully inefficient. Would implementing something in C++ to write the file out be faster (and creating a wrapper that gets called by C#)? – ArKi Dec 02 '16 at 03:48
  • That sounds like a good approach. Assuming use of C++/CLI you should be able to just add a reference to you C++ library and use it like any other C# class. – meganaut Dec 02 '16 at 03:54

1 Answers1

3

Take a look at the UnmanagedMemoryStream type:

Image cameraData = YourSDKFunction();
using (var camera = new UnmanagedMemoryStream(cameraData.data, (int64)cameraData.dataSize))
using (var outFile = new FileStream("outputFile.jpg"))
{
     camera.CopyTo(outFile);
}
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • This probably the way to go in terms of simplicity to implement. I will note that this doesn't avoid allocating a `byte[]` it just hides it inside `CopyTo`. However it is going to use a buffer (default size is 81920) which doesn't allocate nearly what a whole image would require to hold in memory at one time. – Mike Zboray Dec 02 '16 at 06:15