MATLAB mexCallMatlab 导致崩溃
MATLAB mexCallMatlab causes crash
我正在尝试在 mex 中开发一个函数。该函数的目的应该是将 window 滑动到 3D 图像上并在 window 中应用一些函数。目前我被卡住了,因为当算法到达 padarray
函数的调用时,MATLAB 崩溃了。
到目前为止我写了这几行代码
#include <iostream>
#include "mex.h"
#include "matrix.h"
using namespace std;
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
#define O_IMAGE plhs[0]
#define I_IMAGE prhs[0]
#define I_PADSIZE prhs[1]
#define I_FUN prhs[2]
#define I_OPTION prhs[3]
// Argument Checking:
if(nrhs < 1 || nrhs > 4) /* Check the number of arguments */
mexErrMsgTxt("Wrong number of input arguments.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
// Variable declarations
static const char padding[] = "symmetric";
const char *windowShape;
const mwSize *dim;
mwSize *dimPad;
mwSize ndim;
double *pad, *windowSize, *thetaStep, *phiStep;
mxArray *inputFun[4], *inputPadFun[3], *input_image, *imagePad, *output_image;
/*Get dimensions of input image*/
ndim = mxGetNumberOfDimensions(I_IMAGE);
dim = mxGetDimensions(I_IMAGE);
/* Create dimensions of padded image*/
dimPad = (mwSize *) mxCalloc(ndim, sizeof(mwSize));
dimPad = (mwSize *) memcpy((void *) dimPad,(void *) dim, ndim*sizeof(mwSize));
pad = mxGetPr(I_PADSIZE);
for (int i=0;i<ndim;++i)
{
dimPad[i] += 2*pad[i];
}
/*Get pointer to the input image*/
input_image = (mxArray *) mxGetData(I_IMAGE);
/* Create output image*/
O_IMAGE = mxCreateNumericArray(ndim, dim, mxDOUBLE_CLASS, mxREAL);
output_image = (mxArray *) mxGetData(O_IMAGE);
/* Create padded image*/
imagePad = mxCreateNumericArray(ndim, dimPad, mxDOUBLE_CLASS, mxREAL);
// Padding input matrix
inputPadFun[0] = input_image;
inputPadFun[1] = (mxArray *)(pad);
inputPadFun[2] = (mxArray *)(padding);
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
// Clean UP
mxFree(dimPad);
mxDestroyArray(imagePad);
}
我在 mexCallMATLAB
检查了输入和输出图像的尺寸,它们似乎是正确的。我真的不明白我做错了什么。任何帮助是极大的赞赏!
有几个问题转换。
由于 pad
是 double*
,您在这里进行了无意义的转换:
(mxArray *)(pad)
类似 padding
是 const char[]
,你不能这样做
(mxArray *)(padding)
在接下来的行中,mxGetData
returns void*
到具有 基本类型 基础数据的缓冲区(double
、single
等),但您将其转换为 mxArray*
:
(mxArray *) mxGetData(prhs[0]);
请记住,mxArray
是 MathWorks 定义的不透明对象类型,您必须使用它们的函数来创建这些对象。您也只能处理指向它们的指针。
还有其他问题...
代码
这是一个 C++ 示例,说明您可以如何更改代码:
// padarray_BugsFree.cpp
#include <iostream>
#include "mex.h"
#include "matrix.h"
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
if(nrhs != 2)
mexErrMsgTxt("Wrong number of input arguments:\n\t"
"Iout = padarray_BugsFree(I,pad)");
if(nlhs > 1)
mexErrMsgTxt("Too many output arguments:\n\t"
"Iout = padarray_BugsFree(I,pad)");
if(!(mxIsDouble(prhs[0]) && mxIsDouble(prhs[1])))
mexErrMsgTxt("Inputs must be double");
mwSize ndim = mxGetNumberOfDimensions(prhs[0]);
const mwSize *dim = mxGetDimensions(prhs[0]);
if (ndim != mxGetNumberOfElements(prhs[1]))
mexErrMsgTxt("pad must be equal to ndims(I)");
const double *pad = mxGetPr(prhs[1]);
mwSize *dimPad = (mwSize *) mxCalloc(ndim, sizeof(mwSize));
for (int i=0; i<ndim; ++i) {
dimPad[i] = dim[i] + 2*pad[i];
}
mxArray *imagePad = mxCreateNumericArray(ndim, dimPad, mxDOUBLE_CLASS, mxREAL);
mxFree(dimPad);
// Padding input matrix
mxArray *padding = mxCreateString("symmetric");
mxArray *inputPadFun[3];
inputPadFun[0] = const_cast<mxArray*>(prhs[0]);
inputPadFun[1] = const_cast<mxArray*>(prhs[1]);
inputPadFun[2] = padding;
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
mxDestroyArray(padding);
// do something with the padded image and generate output
plhs[0] = mxDuplicateArray(imagePad); // in place of useful operations
mxDestroyArray(imagePad);
}
演示
>> I = magic(3)
I =
8 1 6
3 5 7
4 9 2
>> pad = [2 2]
pad =
2 2
>> padarray_BugsFree
Error using padarray_BugsFree
Wrong number of input arguments:
Iout = padarray_BugsFree(I,pad)
>> Iout = padarray_BugsFree(I,pad)
Iout =
5 3 3 5 7 7 5
1 8 8 1 6 6 1
1 8 8 1 6 6 1
5 3 3 5 7 7 5
9 4 4 9 2 2 9
9 4 4 9 2 2 9
5 3 3 5 7 7 5
备注
参考以下帖子如何使用mexCallMATLAB
:
您还可以按如下方式构建 RHS 输入数组:
mxArray *inputPadFun[] = {const_cast<mxArray*>(prhs[0]),
const_cast<mxArray*>(prhs[1]), padding};
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
我正在尝试在 mex 中开发一个函数。该函数的目的应该是将 window 滑动到 3D 图像上并在 window 中应用一些函数。目前我被卡住了,因为当算法到达 padarray
函数的调用时,MATLAB 崩溃了。
到目前为止我写了这几行代码
#include <iostream>
#include "mex.h"
#include "matrix.h"
using namespace std;
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
#define O_IMAGE plhs[0]
#define I_IMAGE prhs[0]
#define I_PADSIZE prhs[1]
#define I_FUN prhs[2]
#define I_OPTION prhs[3]
// Argument Checking:
if(nrhs < 1 || nrhs > 4) /* Check the number of arguments */
mexErrMsgTxt("Wrong number of input arguments.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
// Variable declarations
static const char padding[] = "symmetric";
const char *windowShape;
const mwSize *dim;
mwSize *dimPad;
mwSize ndim;
double *pad, *windowSize, *thetaStep, *phiStep;
mxArray *inputFun[4], *inputPadFun[3], *input_image, *imagePad, *output_image;
/*Get dimensions of input image*/
ndim = mxGetNumberOfDimensions(I_IMAGE);
dim = mxGetDimensions(I_IMAGE);
/* Create dimensions of padded image*/
dimPad = (mwSize *) mxCalloc(ndim, sizeof(mwSize));
dimPad = (mwSize *) memcpy((void *) dimPad,(void *) dim, ndim*sizeof(mwSize));
pad = mxGetPr(I_PADSIZE);
for (int i=0;i<ndim;++i)
{
dimPad[i] += 2*pad[i];
}
/*Get pointer to the input image*/
input_image = (mxArray *) mxGetData(I_IMAGE);
/* Create output image*/
O_IMAGE = mxCreateNumericArray(ndim, dim, mxDOUBLE_CLASS, mxREAL);
output_image = (mxArray *) mxGetData(O_IMAGE);
/* Create padded image*/
imagePad = mxCreateNumericArray(ndim, dimPad, mxDOUBLE_CLASS, mxREAL);
// Padding input matrix
inputPadFun[0] = input_image;
inputPadFun[1] = (mxArray *)(pad);
inputPadFun[2] = (mxArray *)(padding);
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
// Clean UP
mxFree(dimPad);
mxDestroyArray(imagePad);
}
我在 mexCallMATLAB
检查了输入和输出图像的尺寸,它们似乎是正确的。我真的不明白我做错了什么。任何帮助是极大的赞赏!
有几个问题转换。
由于 pad
是 double*
,您在这里进行了无意义的转换:
(mxArray *)(pad)
类似 padding
是 const char[]
,你不能这样做
(mxArray *)(padding)
在接下来的行中,mxGetData
returns void*
到具有 基本类型 基础数据的缓冲区(double
、single
等),但您将其转换为 mxArray*
:
(mxArray *) mxGetData(prhs[0]);
请记住,mxArray
是 MathWorks 定义的不透明对象类型,您必须使用它们的函数来创建这些对象。您也只能处理指向它们的指针。
还有其他问题...
代码
这是一个 C++ 示例,说明您可以如何更改代码:
// padarray_BugsFree.cpp
#include <iostream>
#include "mex.h"
#include "matrix.h"
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
if(nrhs != 2)
mexErrMsgTxt("Wrong number of input arguments:\n\t"
"Iout = padarray_BugsFree(I,pad)");
if(nlhs > 1)
mexErrMsgTxt("Too many output arguments:\n\t"
"Iout = padarray_BugsFree(I,pad)");
if(!(mxIsDouble(prhs[0]) && mxIsDouble(prhs[1])))
mexErrMsgTxt("Inputs must be double");
mwSize ndim = mxGetNumberOfDimensions(prhs[0]);
const mwSize *dim = mxGetDimensions(prhs[0]);
if (ndim != mxGetNumberOfElements(prhs[1]))
mexErrMsgTxt("pad must be equal to ndims(I)");
const double *pad = mxGetPr(prhs[1]);
mwSize *dimPad = (mwSize *) mxCalloc(ndim, sizeof(mwSize));
for (int i=0; i<ndim; ++i) {
dimPad[i] = dim[i] + 2*pad[i];
}
mxArray *imagePad = mxCreateNumericArray(ndim, dimPad, mxDOUBLE_CLASS, mxREAL);
mxFree(dimPad);
// Padding input matrix
mxArray *padding = mxCreateString("symmetric");
mxArray *inputPadFun[3];
inputPadFun[0] = const_cast<mxArray*>(prhs[0]);
inputPadFun[1] = const_cast<mxArray*>(prhs[1]);
inputPadFun[2] = padding;
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
mxDestroyArray(padding);
// do something with the padded image and generate output
plhs[0] = mxDuplicateArray(imagePad); // in place of useful operations
mxDestroyArray(imagePad);
}
演示
>> I = magic(3)
I =
8 1 6
3 5 7
4 9 2
>> pad = [2 2]
pad =
2 2
>> padarray_BugsFree
Error using padarray_BugsFree
Wrong number of input arguments:
Iout = padarray_BugsFree(I,pad)
>> Iout = padarray_BugsFree(I,pad)
Iout =
5 3 3 5 7 7 5
1 8 8 1 6 6 1
1 8 8 1 6 6 1
5 3 3 5 7 7 5
9 4 4 9 2 2 9
9 4 4 9 2 2 9
5 3 3 5 7 7 5
备注
参考以下帖子如何使用mexCallMATLAB
:
您还可以按如下方式构建 RHS 输入数组:
mxArray *inputPadFun[] = {const_cast<mxArray*>(prhs[0]),
const_cast<mxArray*>(prhs[1]), padding};
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");