First, I've read the a few questions regarding this issue, the most helpful being: Passing bitmap from c# to c++
I was unable to get the provided solutions to work as I kept getting an AccessViolationException
.
What I'm attempting to do is pass bitmap data to an unmanaged c++ dll. To do this I created a struct which holds a pointer to the image data as well as its length. I'm using a struct as I plan on passing in multiple images (in a single call) to the unmanaged API.
What I implemented works but I have a feeling there is probably some serious drawbacks so I'm curious as to what those drawbacks could be.
My current solution uses a generic pointer to hold the image data. This of course would be a drawback as I lose type safety. Anyway here is the relevant code.
c++ dll
raw_image.h
struct raw_image
{
void* data;
int size;
};
alignment.cpp (exports)
ALIGNMENT_API void submit( raw_image& img )
{
cv::Mat mat = cv::imdecode( cv::_InputArray(
static_cast<uchar*>( img.data ), img.size ), cv::IMREAD_COLOR );
cv::imshow( "image", mat );
cv::waitKey( );
cv::destroyWindow( "image" );
}
C# dll
RawImage.cs
[StructLayout( LayoutKind.Sequential )]
internal unsafe struct RawImage
{
internal void* ImageData;
internal int Length;
}
Aligner.cs (import)
[DllImport( "alignment-vc141-mtd-x64.dll", CallingConvention =
CallingConvention.Cdecl )]
static extern void submit( RawImage img );
And this is where I pass the image to the unmanaged API.
using( var bitmap = new Bitmap( "AlignmentCenter.jpg" ) )
using( var stream = new MemoryStream( ) )
{
bitmap.Save( stream, ImageFormat.Jpeg );
var source = stream.ToArray( );
fixed( void* ptr = source )
{
var raw = new RawImage
{
ImageData = ptr,
Length = source.Length
};
submit( raw );
}
}
Is what I'm doing unsafe? Am I copying more than I should?
One last thing, I know about EmguCv
and I've used it in the past but I won't be using it here.