I'm trying to write a thin wrapper (of very little functionality that i actually need) around OpenCV 3 in C++/CLI to be consumed from C#.
However i'm not quite figuring out how i can store my Mat variables in the managed class, if i try to do it as is i get, as expected, an error stating that i can't mix native and non native members.
From what i gather i'm supposed to new up my native members and store a pointer to them, however i can't do that in all cases as a lot of OpenCV methods return a Mat and not a pointer to a Mat.
After some testing i saw that: - If i store a pointer to a new Mat(); this works just fine and it will still be available later on - If i try to store a pointer to a Mat (as returned by imread) it will be corrupted after the method ends.
What would be the proper way to store the Mat or a pointer to it?
Sample code:
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);
}
};
Note: i'm not looking for alternatives to writing my own wrapper, none of the ones i've tried were satisfactory.