calling c function from MATLAB?

Deependra Mishra

I want to call a c function from matlab, for that I tried writing a wrapper function using 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??

#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:

#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;
}
rayryeng

In your main function, outdata is a pointer to a double, yet your function midd takes in an actual double itself. 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:

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:

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

You don't need height*width as the offset. r + height*c is enough to access a single channel 2D matrix in column-major order. You only need to offset by height*width if you have a multi-channel image. 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. It's going to unnecessarily flood your Command Prompt with print messages since you have it inside a nested for loop. 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.

See my post on how to get that set up here: Preventing a MEX file from crashing in MATLAB

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Calling Matlab function from c# + OOP

From Dev

Calling main function from another function in C

From Dev

matlab to R: function calling and @

From Dev

Calling a Matlab function in Fortran

From Dev

Calling a C++ Function from C Program

From Dev

Calling a python function from MATLAB, generates an object with only some attribute

From Dev

Matlab: Calling a function of a .m file from another .m file

From Dev

Calling Matlab function from python: "initializer must be a rectangular nested sequence"

From Dev

Calling python from matlab

From Java

Calling Java from MATLAB?

From Java

Calling Java from MATLAB

From Dev

Calling a function from within itself in C#

From Dev

Calling a D function directly from C++

From Dev

Calling a Fortran function from Qt C++

From

error on calling go function from c

From Dev

Calling C function with pointers from F#

From

Calling function from Go in C#

From Dev

Calling a template function from a C file

From Dev

Calling Java function from Qt C++

From Dev

Segfault calling c function from assembly

From Dev

Calling C function with **int parameter from Fortran

From Dev

Calling c++ function from python

From Dev

Calling C function from returned pointer in NodeJS

From Dev

Calling the agrep .Internal C function from Rcpp

From Dev

c++ Calling a function from a class pointer

From Dev

Calling an F# Function from C#

From Dev

Calling C function from Fortran with pointers

From Dev

Calling a function in a .cpp file from a .c file

From Dev

Calling a C function from Assembly -- switching calling convention