MATLAB mexCallMatlab导致崩溃

MATLAB mexCallMatlab导致崩溃,c,matlab,mex,sliding-window,C,Matlab,Mex,Sliding Window,我正试图在mex中开发一个函数。该功能的目的应该是将窗口滑动到3D图像上,并在窗口内应用一些功能。目前我被卡住了,因为当算法到达padarray函数的调用时,MATLAB崩溃了 到目前为止,我写了这些代码行 #include <iostream> #include "mex.h" #include "matrix.h" using namespace std; void mexFunction(int nlhs,mxArray *plhs[], int nrhs,

我正试图在mex中开发一个函数。该功能的目的应该是将窗口滑动到3D图像上,并在窗口内应用一些功能。目前我被卡住了,因为当算法到达
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);
}
#包括
#包括“mex.h”
#包括“矩阵h”
使用名称空间std;
void MEX函数(int nlhs、mxArray*plhs[]、int nrhs、const mxArray*prhs[]){
#定义O_图像PLH[0]
#定义I_图像PRH[0]
#定义I_焊盘尺寸PRH[1]
#定义I_FUN PRH[2]
#定义I_选项prhs[3]
//参数检查:
如果(nrhs<1 | | nrhs>4)/*检查参数的数量*/
mexErrMsgTxt(“输入参数的数目错误”);
否则如果(nlhs>1)
mexErrMsgTxt(“太多的输出参数”);
//变量声明
静态常量字符填充[]=“对称”;
常量字符*窗口形状;
常数mwSize*dim;
mwSize*dimPad;
mw-ndim;
双*pad、*windowSize、*thetestp、*phiStep;
mxArray*inputFun[4],*inputPadFun[3],*input_image,*imagePad,*output_image;
/*获取输入图像的尺寸*/
ndim=mxGetNumberOfDimensions(I_图像);
dim=mxGetDimensions(I_图像);
/*创建填充图像的尺寸*/
dimPad=(mwSize*)mxCalloc(ndim,sizeof(mwSize));
dimPad=(mwSize*)memcpy((void*)dimPad,(void*)dim,ndim*尺寸(mwSize));
焊盘=mxGetPr(I_焊盘尺寸);

对于(int i=0;i有几个有问题的类型转换

由于
pad
是一个
double*
,您在这里做的是一个无意义的演员阵容:

(mxArray *)(pad)
类似地,对于
填充
这是一个
常量字符[]
,您不能这样做

(mxArray *)(padding)
在下一行中,
mxGetData
向缓冲区返回一个
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);
}
注释

如何使用
mexCallMATLAB
,请参考以下文章:

您还可以按如下方式构建RHS输入数组:

mxArray *inputPadFun[] = {const_cast<mxArray*>(prhs[0]),
                          const_cast<mxArray*>(prhs[1]), padding};
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");
mxArray*inputPadFun[]={const_cast(prhs[0]),
const_cast(prhs[1]),padding};
mexCallMATLAB(1,&imagePad,3,inputPadFun,“padarray”);

当我做错误的内存填充时,我通常使用Matlab chrash和mex文件。请检查您是否正确创建了
imagePad
。谢谢您的建议。我如何检查内存分配是否正确?我检查了尺寸是否正确,并且
dim
dimPad
都具有预期值。我不知道在调用函数之前,请不要使用
imagePad
,因此我不明白如何处理内存问题。如果
imagePad
不够大,无法存储填充数组,则表示您存在内存访问错误!我已检查并
ndim=3
无问题,并且
dimPad=[42]
这也没问题,因为原始图像是
32x32x32
,填充数组是
5x5x5
。我认为您的
padding
字符串有问题。尝试使用
mxCreateString
而不是将
padding
转换为
inputPadF的第三个参数的
mxArray
un
。您也不需要投射
pad
。这已经是
mxArray
指针,所以只需执行
prhs[1]
I_PADSIZE
。漂亮:D。因此我对转换的怀疑确实是正确的。非常感谢。明天我将尝试你的解决方案,但肯定会奏效,我会接受。让我检查我是否理解正确:如果我有基本类型,我无法将它们转换到
mxArray*
来创建
mxArray*
,但是我需要使用matlab的特定功能?@BugsFree对。你通常不能(以有意义的方式)强制转换在指针之间,除了
void*
。例如,将
double
转换为
single
是可以的,但将
double*
转换为
single*
是没有意义的。@rayryeng确实是的。这里有很多时髦的转换。:)
mxArray *inputPadFun[] = {const_cast<mxArray*>(prhs[0]),
                          const_cast<mxArray*>(prhs[1]), padding};
mexCallMATLAB(1, &imagePad, 3, inputPadFun, "padarray");