我有一个由三部分组成的项目:
-
托管的C#项目有一个回调,它给了我一个位图(它应该有PixelFormat=Format24bppRgb)。我已经尝试了几种方法来将位图转换为我可以传递到第2部分的东西,这是我尝试的最后一件事:
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); }
-
托管C++/CLI包装项目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); }
-
使用OpenCV的非托管C++应用程序。我想用将这些数据加载到Mat中
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; }
当到达imwrite函数时,将引发异常:"System.Runtime.InteropServices.SEHException(0x80004005)"。它没有说太多,但我猜我传递到Mat的数据在整理时已经损坏了。
以前,我试图在没有包装器的情况下传递数据:
[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);
}
这起到了作用(它将位图保存到文件中),但由于DLL在我终止进程之前一直处于附加状态,因此该解决方案对我来说不够好。我也不想将Mat类"镜像"到我的项目中,因为我知道Mat应该接受来自某些字符*的数据。
请帮忙,我该怎么做?我是否进行了错误的类型转换?
谢谢。
我已经将第2部分从memcpy非托管内存更改为本机内存,只是为了确保这一点。但我的代码真正的问题是,每次我想得到一个新的Mat时,我都会调用Mat构造函数:
Mat myMat;
int MyClass::GetBitmap(unsigned char* s_in) {
myMat = Mat(...)
}
相反,我做了:
Mat myMat;
int MyClass::GetBitmap(unsigned char* s_in) {
Mat aux;
aux = Mat(...)
aux.copyTo(myMat);
aux.release();
}
现在我的代码运行得很好。
编辑:删除了一些使用new Mat(...)
的部分,这是一个拼写错误,它无法编译,因为我使用的是Mat,而不是Mat*。