我想在C++中使用C++/CLI中的OpenCV 3编写一个薄包装(实际上我需要的功能非常少)。在不使用新的情况下将原生数据存储在C++/cli中
但是我不是很清楚如何我可以将我的Mat变量存储在托管类中,如果我尝试这样做,因为我得到,如预期的那样,错误指出我不能混合本机和非本地成员。
从我收集我应该新的我的本地成员和存储一个指针,但我不能这样做在所有情况下,因为许多OpenCV方法返回一个垫,而不是一个指针垫。
经过一些测试,我看到: - 如果我存储一个指向新的Mat();这工作得很好,它将在 后面仍然可用 - 如果我尝试存储指向Mat的指针(由imread返回),它将在方法结束后损坏。
什么是正确的方式来存储垫或指针?
示例代码:
public ref class Matrix
{
private:
Mat* mat;
msclr::interop::marshal_context marshalcontext;
public:
static Matrix^ FromFile(System::String^ FileName)
{
Matrix^ ret = gcnew Matrix();
msclr::interop::marshal_context context;
std::string StdFileName = context.marshal_as<std::string>(FileName);
Mat tmpmat = imread(StdFileName);
Mat * tmpmatptr = new Mat(50, 50, 1); // Works in all cases
//Mat * tmpmatptr = &tmpmat; // will NOT work out of the scope of this method
Console::WriteLine(tmpmat.cols); // Always works
Console::WriteLine(tmpmat.rows); // Always works
Console::WriteLine(tmpmatptr->cols); // Always works
Console::WriteLine(tmpmatptr->rows); // Always works
ret->mat = tmpmatptr;
return ret;
}
void Save(System::String^ FileName)
{
std::string StdFileName = marshalcontext.marshal_as<std::string>(FileName);
// Code bellow works if tmpmatptr in previous method was assigned a new Mat, doesn't work if it was assigned a pointer to imread result
Console::WriteLine(mat->rows);
Console::WriteLine(mat->cols);
imwrite(StdFileName, *mat);
}
};
注:我不是在寻找替代品写我自己的包装,没有那些我已经试过的满意。
这是一个标准的[悬摆指针错误(https://en.wikipedia.org/维基/ Dangling_pointer)。使用ret-> mat = new Mat(tmpmat)创建存储在堆上的副本。不要忘记Matrix中的析构函数和终结器,它需要再次摧毁它。 –