问题
I have a project with 3 parts:
Managed C# project with a callback which gives me a Bitmap (it should have PixelFormat = Format24bppRgb). I've tried several ways to convert the Bitmap into something I could pass to part 2, that's the last thing I've tried:
public int BufferCB(IntPtr pBuffer, int BufferLen) { byte[] aux = new byte[BufferLen]; Marshal.Copy(pBuffer, aux, 0, BufferLen); String s_aux = System.Text.Encoding.Default.GetString(aux); wrappedClassInstance.GetBitmap(s_aux); }
Managed C++/CLI to wrap item 3:
int WrappedClass::GetBitmap(array<System::Byte>^ s_in) { pin_ptr<unsigned char> pin = &s_in[0]; unsigned char* p = pin; return privateImplementation->GetBitmap(p); }
Unmanaged C++ application that uses OpenCV. I want to load this data into a Mat with:
Mat myMat; int NativeClass::GetBitmap(unsigned char *s_in) { // If there's no input: if (!s_in) { return -1; } /* h and w are defined elsewhere */ myMat = Mat(h, w, CV_8UC3, (void *)s_in, Mat::AUTO_STEP)); imwrite("test.bmp", myMat); return 0; }
When the the imwrite function is reached an exception is thrown: "System.Runtime.InteropServices.SEHException (0x80004005)". It doesn't say much, but I'm guessing the data I passed into the Mat got corrupted when I've marshalled it.
Before, I was trying to pass the data without a wrapper:
[DllImport("mydll.dll", ...)]
static extern void GetBitmap(IntPtr pBuffer, int h, int w);
void TestMethod(IntPtr pBuffer, int BufferLen)
{
// h and w defined elsewhere
// GetBitmap is essentially the same as in item 3.
GetBitmap(pBuffer, BufferLen, h, w);
}
and that worked (it saved the Bitmap into the file), but because the DLL stays attached until I kill the process that solution is not good enough for me. I also don't want to "mirror" the Mat class into my project, as I know Mat should accept data from some char*.
Please help, how can I do this? Am I doing wrong type conversions?
Thank you.
回答1:
I've changed part 2 to memcpy unmanaged memory into native memory, just to be sure. But the real problem with my code was that everytime I wanted to get a new Mat, I'd call Mat constructor:
Mat myMat;
int MyClass::GetBitmap(unsigned char* s_in) {
myMat = Mat(...)
}
Instead, I did:
Mat myMat;
int MyClass::GetBitmap(unsigned char* s_in) {
Mat aux;
aux = Mat(...)
aux.copyTo(myMat);
aux.release();
}
... and now my code is working perfectly.
EDIT:
Removed some parts which used new Mat(...)
, it was a typo and it wouldn't compile because I'm using Mat, not Mat*.
来源:https://stackoverflow.com/questions/29290428/how-to-pass-managed-bitmap-from-c-sharp-to-wrapped-unmanaged-opencvs-mat