简体   繁体   English

从MATLAB调用C函数?

[英]calling c function from MATLAB?

I want to call ac function from matlab, for that I tried writing a wrapper function using MEX. 我想从matlab调用ac函数,为此我尝试使用MEX编写包装函数。 While compiling I am getting error C2109: subscript requires array or pointer type and error C2440: 'function' : cannot convert from 'double *' to 'double' Can anyone help me where i did the mistake?? 编译时出现错误C2109:下标需要数组或指针类型,并且错误C2440:'function':无法从'double *'转换为'double'有人可以帮助我在哪里出错?

#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);

}

The c function i am trying to call is as follows: 我试图调用的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;
}

In your main function, outdata is a pointer to a double , yet your function midd takes in an actual double itself. 在你的主要功能, outdata是一个指向double ,但你的函数midd需要在实际的double本身。 That's why you're getting that error in type. 这就是为什么您会收到类型错误的原因。

Simply change your function declaration so that the first input accepts a pointer to a double : 只需更改函数声明,以便第一个输入接受一个指向double的指针:

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

Minor Note 次要音符

I question your copying of your image data back to a MEX array here: 我在这里质疑您将图像数据复制回MEX阵列的情况:

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

You don't need height*width as the offset. 您不需要height*width作为偏移量。 r + height*c is enough to access a single channel 2D matrix in column-major order. r + height*c足以按列优先顺序访问单个通道2D矩阵。 You only need to offset by height*width if you have a multi-channel image. 如果您有多通道图像,则只需要偏移height*width That offset allows you to access image data in other channels... and since you only have single channel data (it looks like so...), this offset isn't required. 该偏移量允许您访问其他通道中的图像数据...并且由于您只有单个通道数据(看起来像这样...),因此不需要此偏移量。

Therefore, you simply need to do: 因此,您只需要执行以下操作:

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

If you don't do this, I suspect you will eventually get segmentation faults because you'll eventually access parts of memory you aren't allowed to access. 如果您不这样做,我怀疑您最终会遇到分段错误,因为您最终将访问不允许访问的部分内存。


Also, once you fully test your code, get rid of the mexPrintf statements. 此外,一旦完全测试了代码,就摆脱mexPrintf语句。 It's going to unnecessarily flood your Command Prompt with print messages since you have it inside a nested for loop. 由于您将其放在嵌套的for循环中,因此它将不必要地在命令提示符中填充打印消息。 I suspect you did this for debugging, and that's perfectly fine, but I would suggest you attach the MEX function to an actual debugger and debug your code properly instead of the print statements. 我怀疑您是为了调试而这样做的,这很好,但是我建议您将MEX函数附加到实际的调试器上,并正确调试代码,而不是打印语句。

See my post on how to get that set up here: Preventing a MEX file from crashing in MATLAB 在这里查看有关如何进行设置的文章: 防止MEX文件在MATLAB中崩溃

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM