从MATLAB调用c函数?

问题描述:

我想从matlab中调用一个c函数,为此我尝试使用MEX编写一个包装函数。编译时我得到 错误C2109:下标需要数组或指针类型 和错误C2440:'function':无法从'double *'转换为'double' 任何人都可以帮助我在哪里做错了?从MATLAB调用c函数?

#include "mex.h" 
#include "matrix.h" 
#include "CVIPtoolkit.h" 
#include "CVIPtools.h" 
#include "CVIPmatrix.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 


void midd(double outdata, int type, int height, int width){ 
    Image *outputImage; 
    byte **output; 
    int r,c; 

    mexPrintf("type %d\n", type); 
    mexPrintf("height %d\n", height); 
    mexPrintf("width %d\n", width); 

    outputImage=new_Image (PGM, GRAY_SCALE, 0, height, width, CVIP_BYTE, REAL); 
    outputImage = h_image(type, height,width); 

    output = getData_Image(outputImage, 0); 
    for(r=0; r < height; r++) { 
      for(c=0; c < width; c++) 
      { 
       mexPrintf("type %d\n", type); 
       mexPrintf("height %d\n", height); 
       mexPrintf("width %d\n", width); 

       outdata[r+height*c+height*width] =output[r][c];  /* passing data back to MATLAB variable from CVIPtools variable */ 
      } 
     }  
} 


void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{ 
    double *outdata; 
    int type, height, width; 

    // double *indata = (double *)mxGetData(prhs[0]); 

    type = mxGetScalar(prhs[0]); 
    height = mxGetScalar(prhs[1]); 
    width = mxGetScalar(prhs[2]); 

    mexPrintf("type %d\n", type); 
    mexPrintf("height %d\n", height); 
    mexPrintf("width %d\n", width); 

    plhs[0] = mxCreateDoubleMatrix(height,width,mxREAL); 

    outdata = mxGetData(plhs[0]); 
    midd(outdata, type, height, width); 

} 

C函数我试图拨打如下:

#include "CVIPtoolkit.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 


Image * 
h_image(int type, unsigned int height, unsigned int width){ 

    /* type = 1, Constant 
    * type = 2, Fixed mask 
    * type = 3, Gaussian 
    */ 

    unsigned int r, c, hf_w = width/2, hf_h = height/2; 
    Image *outimage; 
    float **outdata, sum = 0.0, sigma, tmp1, tmp2, tmp; 

    if (height < 3 || width < 3) { 
     fprintf(stderr, "Masksize too small, at least 3x3\n"); 
     return (Image *)NULL; 
    } 

    outimage = new_Image(PGM, GRAY_SCALE, 1, height, width, CVIP_FLOAT, REAL); 
    outdata = (float **)getData_Image(outimage, 0); 

    switch (type) { 
     case 1: 
      for (r = 0; r < height; r++) 
       for (c = 0; c < width; c++) { 
        outdata[r][c] = 1.0; 
        sum += outdata[r][c]; 
       } 
      break; 
     case 2: 
      for (r = 0; r < height; r++) 
       for (c = 0; c < width; c++) { 
        outdata[r][c] = 1.0; 
        sum += outdata[r][c]; 
       } 
      outdata[height/2][width/2] = height * width; 
      sum = sum - 1.0 + outdata[height/2][width/2]; 
      break; 
     case 3: 
      c = (width + height) /4; 
      r = (width + height) /2; 
      sigma = sqrt(c*c/(2 * log(2) + (r - 3) * log(3))); 
      sigma = 1.0/2.0 /sigma/sigma; 
      tmp = width * height; 
      for (r = 0; r < height; r++) 
       for (c = 0; c < width; c++) { 
        tmp1 = (r-hf_h)*(r-hf_h); tmp2 = (c-hf_w)*(c-hf_w); 
        outdata[r][c] = tmp*exp(- (tmp1 + tmp2) * sigma); 
        sum += outdata[r][c]; 
       } 
      break; 
     default: 
      fprintf(stderr, "Incorrect mask type number: %d\n", type); 
      return (Image *)NULL; 
    } 

    return outimage; 
} 

在你的主要功能,outdata是一个指向double,但你的函数midd在实际double本身需要。这就是为什么你在类型中得到这个错误。

简单地改变你的函数声明,使第一输入接受一个指向一个double

void midd(double *outdata, int type, int height, int width) 
     //  ^^^^^^^^ 

小注

我怀疑你的图像数据复制回MEX阵列的位置:

outdata[r+height*c+height*width] =output[r][c]; 

您不需要height*width作为抵消。 r + height*c就足以以列主要顺序访问单通道2D矩阵。如果您有多通道图像,则只需要抵消height*width。该偏移允许您访问其他通道中的图像数据...并且由于您只有单通道数据(它看起来像......),因此不需要此偏移量。

因此,你只需要做:

outdata[r + height*c] = output[r][c]; 

如果你不这样做,我怀疑你最终会得到分段错误,因为你最终会访问你不允许的内存部分访问。


此外,一旦你完全测试你的代码,摆脱mexPrintf语句。由于在嵌套的for循环中有它,因此它会不必要地将您的命令提示符填充为打印消息。我怀疑你是否这样做了调试,这很好,但是我建议你将MEX函数附加到实际的调试器上,并正确地调试代码而不是打印语句。

查看我的帖子,了解如何在此处设置:Preventing a MEX file from crashing in MATLAB