本机结构和托管结构在内存中的布局不同,因此跨托管/非托管边界成功传递结构需要额外的步骤来保持数据完整性。 (see here)
一种可能性是在 C++ 端将 cv::Mat 转换为位图,然后使用 PInvoke 在 C# 中获取位图
在 C++ 端你可以使用这个函数,取自here
CBitmap* IplImageToCBitmap(IplImage* img)
{
CDC dc;
CDC memDC;
if (!dc.CreateDC("DISPLAY", NULL, NULL, NULL))
return NULL;
if (!memDC.CreateCompatibleDC(&dc))
return NULL;
CBitmap* bmp = new CBitmap();
CBitmap* pOldBitmap;
bmp->CreateCompatibleBitmap(&dc, img->width, img->height);
pOldBitmap = memDC.SelectObject(bmp);
CvvImage cvImage; // you will need OpenCV_2.2.0- to use CvvImage
cvImage.CopyOf(img);
cvImage.Show(memDC.m_hDC, 0, 0, img->width, img->height, 0, 0);
cvImage.Destroy();
memDC.SelectObject(pOldBitmap);
memDC.DeleteDC();
dc.DeleteDC();
return bmp;
}
然后以这种方式包装你的函数
extern "C" __declspec( dllexport) HRESULT WrappedFunction(HBITMAP * hBitmap);
HRESULT WrappedFunction(/*[out]*/ HBITMAP * hBitmap)
{
cv::Mat aMat = YourFunction();
CBitmap *bmp = IplImageToCBitmap((IplImage*) &aMat);
*hBitmap = (HBITMAP)bmp->Detach();
return S_OK;
}
然后,在 C# 方面你可以这样做:
IntPtr ret;
WrappedFunction( out ret );
Bitmap b = Image.FromHbitmap( ret );