将 Mat 对象 C++ 传递给 Unity
pass Mat object C++ to Unity
我想从 C++ 代码 return 一个 Mat 对象到 Unity。但是我在 C++ 部分遇到访问冲突错误
Unity Editor [version: Unity 2017.3.0f3_a9f86dcd79df]
SaliencyCV.dll caused an Access Violation (0xc0000005)
in module SaliencyCV.dll at 0033:270027f0.
Error occurred at 2018-03-06_235212.
C:\Program Files\Unity\Editor\Unity.exe, run by Dilara.
43% memory in use.
16266 MB physical memory [9199 MB free].
18698 MB paging file [9861 MB free].
134217728 MB user address space [134185466 MB free].
Read from location 990d0000 caused an access violation.
这是 C++ 代码:
uchar* cppMethod(uchar* frameData, int WIDTH, int HEIGHT, int* rows, int* cols)
{
Mat img(HEIGHT, WIDTH, CV_8UC3);
img.data = frameData;
flip(img, img, 0);
Mat result = calculateSaliency(img);
*rows = result.rows;
*cols = result.cols;
int length = result.rows * result.cols * 3;
uchar* tmpArr = result.data;
uchar* resultArray = new uchar[length];
for (int i = 0; i < length; i++)
{
resultArray[i] = tmpArr[i];
}
return resultArray;
}
有人可以帮助我吗?
您应该调用正确的 Mat
构造函数,which accepts external data pointer, to make the object not release/destruct the corresponding memory location data
points to. You can read about this behaviour in Mat::release()
。
你的代码有问题
Mat img(HEIGHT, WIDTH, CV_8UC3)
分配了一个 CV_8UC3
类型的内存块,大小为 HEIGHT*WIDTH
,它没有被使用(因为你正在改变 data
成员变量指向一个无论如何,不同的内存位置),
- 在函数退出时,
img
被析构,这会导致调用 release()
,后者又会析构 frameData
,即 而不是 预期的行为。
将前两行改为阅读
Mat img(HEIGHT, WIDTH, CV_8UC3, frameData);
并且如果您将 resultArray
传递给 C#,您很可能 而不是 管理 pointed-to-memory 的生命周期,您很可能有内存泄漏。 @Programmer 在他对你之前问题的回答中已经建议你应该在 C# 中分配内存,将其传递给 C++,并在 C++ 端写入 in-place。
简而言之,你应该有这样的东西:
#include <algorithm>
void cppMethod(uchar *frameData, uchar *out, const int WIDTH, const int HEIGHT,
int *rows, int *cols) {
/* this constructor will not manage frameData's lifetime */
Mat img(HEIGHT, WIDTH, CV_8UC3, frameData);
/* in-place operation */
flip(img, img, 0);
/* local variable --- it will be destructed properly */
Mat result = calculateSaliency(img);
/* well-defined if rows and cols are scalars passed by reference */
*rows = result.rows;
*cols = result.cols;
/* make sure length will not overflow */
int length = result.rows * result.cols * 3;
/* you don't need this */
// uchar *tmpArr = result.data;
/* you sholuld NOT do this */
// uchar *resultArray = new uchar[length];
// use std::copy from <algorithm>
// for (int i = 0; i < length; i++) {
// resultArray[i] = tmpArr[i];
// }
std::copy(result.data, result.data + length, out);
// return resultArray;
}
我想从 C++ 代码 return 一个 Mat 对象到 Unity。但是我在 C++ 部分遇到访问冲突错误
Unity Editor [version: Unity 2017.3.0f3_a9f86dcd79df]
SaliencyCV.dll caused an Access Violation (0xc0000005)
in module SaliencyCV.dll at 0033:270027f0.
Error occurred at 2018-03-06_235212.
C:\Program Files\Unity\Editor\Unity.exe, run by Dilara.
43% memory in use.
16266 MB physical memory [9199 MB free].
18698 MB paging file [9861 MB free].
134217728 MB user address space [134185466 MB free].
Read from location 990d0000 caused an access violation.
这是 C++ 代码:
uchar* cppMethod(uchar* frameData, int WIDTH, int HEIGHT, int* rows, int* cols)
{
Mat img(HEIGHT, WIDTH, CV_8UC3);
img.data = frameData;
flip(img, img, 0);
Mat result = calculateSaliency(img);
*rows = result.rows;
*cols = result.cols;
int length = result.rows * result.cols * 3;
uchar* tmpArr = result.data;
uchar* resultArray = new uchar[length];
for (int i = 0; i < length; i++)
{
resultArray[i] = tmpArr[i];
}
return resultArray;
}
有人可以帮助我吗?
您应该调用正确的 Mat
构造函数,which accepts external data pointer, to make the object not release/destruct the corresponding memory location data
points to. You can read about this behaviour in Mat::release()
。
你的代码有问题
Mat img(HEIGHT, WIDTH, CV_8UC3)
分配了一个CV_8UC3
类型的内存块,大小为HEIGHT*WIDTH
,它没有被使用(因为你正在改变data
成员变量指向一个无论如何,不同的内存位置),- 在函数退出时,
img
被析构,这会导致调用release()
,后者又会析构frameData
,即 而不是 预期的行为。
将前两行改为阅读
Mat img(HEIGHT, WIDTH, CV_8UC3, frameData);
并且如果您将 resultArray
传递给 C#,您很可能 而不是 管理 pointed-to-memory 的生命周期,您很可能有内存泄漏。 @Programmer 在他对你之前问题的回答中已经建议你应该在 C# 中分配内存,将其传递给 C++,并在 C++ 端写入 in-place。
简而言之,你应该有这样的东西:
#include <algorithm>
void cppMethod(uchar *frameData, uchar *out, const int WIDTH, const int HEIGHT,
int *rows, int *cols) {
/* this constructor will not manage frameData's lifetime */
Mat img(HEIGHT, WIDTH, CV_8UC3, frameData);
/* in-place operation */
flip(img, img, 0);
/* local variable --- it will be destructed properly */
Mat result = calculateSaliency(img);
/* well-defined if rows and cols are scalars passed by reference */
*rows = result.rows;
*cols = result.cols;
/* make sure length will not overflow */
int length = result.rows * result.cols * 3;
/* you don't need this */
// uchar *tmpArr = result.data;
/* you sholuld NOT do this */
// uchar *resultArray = new uchar[length];
// use std::copy from <algorithm>
// for (int i = 0; i < length; i++) {
// resultArray[i] = tmpArr[i];
// }
std::copy(result.data, result.data + length, out);
// return resultArray;
}